1*2912Sartem /*************************************************************************** 2*2912Sartem * CVSID: $Id$ 3*2912Sartem * 4*2912Sartem * libhal.c : HAL daemon C convenience library 5*2912Sartem * 6*2912Sartem * Copyright (C) 2003 David Zeuthen, <david@fubar.dk> 7*2912Sartem * 8*2912Sartem * Licensed under the Academic Free License version 2.1 9*2912Sartem * 10*2912Sartem * This program is free software; you can redistribute it and/or modify 11*2912Sartem * it under the terms of the GNU General Public License as published by 12*2912Sartem * the Free Software Foundation; either version 2 of the License, or 13*2912Sartem * (at your option) any later version. 14*2912Sartem * 15*2912Sartem * This program is distributed in the hope that it will be useful, 16*2912Sartem * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*2912Sartem * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*2912Sartem * GNU General Public License for more details. 19*2912Sartem * 20*2912Sartem * You should have received a copy of the GNU General Public License 21*2912Sartem * along with this program; if not, write to the Free Software 22*2912Sartem * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23*2912Sartem * 24*2912Sartem **************************************************************************/ 25*2912Sartem 26*2912Sartem #ifdef HAVE_CONFIG_H 27*2912Sartem # include <config.h> 28*2912Sartem #endif 29*2912Sartem 30*2912Sartem #include <stdio.h> 31*2912Sartem #include <stdlib.h> 32*2912Sartem #include <string.h> 33*2912Sartem #include <dbus/dbus.h> 34*2912Sartem 35*2912Sartem #include "libhal.h" 36*2912Sartem 37*2912Sartem #ifdef ENABLE_NLS 38*2912Sartem # include <libintl.h> 39*2912Sartem # define _(String) dgettext (GETTEXT_PACKAGE, String) 40*2912Sartem # ifdef gettext_noop 41*2912Sartem # define N_(String) gettext_noop (String) 42*2912Sartem # else 43*2912Sartem # define N_(String) (String) 44*2912Sartem # endif 45*2912Sartem #else 46*2912Sartem /* Stubs that do something close enough. */ 47*2912Sartem # define textdomain(String) (String) 48*2912Sartem # define gettext(String) (String) 49*2912Sartem # define dgettext(Domain,Message) (Message) 50*2912Sartem # define dcgettext(Domain,Message,Type) (Message) 51*2912Sartem # define bindtextdomain(Domain,Directory) (Domain) 52*2912Sartem # define _(String) 53*2912Sartem # define N_(String) (String) 54*2912Sartem #endif 55*2912Sartem 56*2912Sartem static char **libhal_get_string_array_from_iter (DBusMessageIter *iter, int *num_elements); 57*2912Sartem 58*2912Sartem static dbus_bool_t libhal_property_fill_value_from_variant (LibHalProperty *p, DBusMessageIter *var_iter); 59*2912Sartem 60*2912Sartem 61*2912Sartem 62*2912Sartem /** 63*2912Sartem * libhal_free_string_array: 64*2912Sartem * @str_array: the array to be freed 65*2912Sartem * 66*2912Sartem * Frees a NULL-terminated array of strings. If passed NULL, does nothing. 67*2912Sartem */ 68*2912Sartem void 69*2912Sartem libhal_free_string_array (char **str_array) 70*2912Sartem { 71*2912Sartem if (str_array != NULL) { 72*2912Sartem int i; 73*2912Sartem 74*2912Sartem for (i = 0; str_array[i] != NULL; i++) { 75*2912Sartem free (str_array[i]); 76*2912Sartem str_array[i] = NULL; 77*2912Sartem } 78*2912Sartem free (str_array); 79*2912Sartem str_array = NULL; 80*2912Sartem } 81*2912Sartem } 82*2912Sartem 83*2912Sartem 84*2912Sartem /** 85*2912Sartem * libhal_get_string_array_from_iter: 86*2912Sartem * @iter: the message iterator to extract the strings from 87*2912Sartem * @num_elements: pointer to an integer where to store number of elements (can be NULL) 88*2912Sartem * 89*2912Sartem * Creates a NULL terminated array of strings from a dbus message iterator. 90*2912Sartem * 91*2912Sartem * Returns: pointer to the string array 92*2912Sartem */ 93*2912Sartem static char ** 94*2912Sartem libhal_get_string_array_from_iter (DBusMessageIter *iter, int *num_elements) 95*2912Sartem { 96*2912Sartem int count; 97*2912Sartem char **buffer; 98*2912Sartem 99*2912Sartem count = 0; 100*2912Sartem buffer = (char **)malloc (sizeof (char *) * 8); 101*2912Sartem 102*2912Sartem if (buffer == NULL) 103*2912Sartem goto oom; 104*2912Sartem 105*2912Sartem buffer[0] = NULL; 106*2912Sartem while (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_STRING) { 107*2912Sartem const char *value; 108*2912Sartem char *str; 109*2912Sartem 110*2912Sartem if ((count % 8) == 0 && count != 0) { 111*2912Sartem buffer = realloc (buffer, sizeof (char *) * (count + 8)); 112*2912Sartem if (buffer == NULL) 113*2912Sartem goto oom; 114*2912Sartem } 115*2912Sartem 116*2912Sartem dbus_message_iter_get_basic (iter, &value); 117*2912Sartem str = strdup (value); 118*2912Sartem if (str == NULL) 119*2912Sartem goto oom; 120*2912Sartem 121*2912Sartem buffer[count] = str; 122*2912Sartem 123*2912Sartem dbus_message_iter_next(iter); 124*2912Sartem count++; 125*2912Sartem } 126*2912Sartem 127*2912Sartem if ((count % 8) == 0) { 128*2912Sartem buffer = realloc (buffer, sizeof (char *) * (count + 1)); 129*2912Sartem if (buffer == NULL) 130*2912Sartem goto oom; 131*2912Sartem } 132*2912Sartem 133*2912Sartem buffer[count] = NULL; 134*2912Sartem if (num_elements != NULL) 135*2912Sartem *num_elements = count; 136*2912Sartem return buffer; 137*2912Sartem 138*2912Sartem oom: 139*2912Sartem fprintf (stderr, "%s %d : error allocating memory\n", __FILE__, __LINE__); 140*2912Sartem return NULL; 141*2912Sartem 142*2912Sartem } 143*2912Sartem 144*2912Sartem /** 145*2912Sartem * libhal_free_string: 146*2912Sartem * @str: the nul-terminated sting to free 147*2912Sartem * 148*2912Sartem * Used to free strings returned by libhal. 149*2912Sartem */ 150*2912Sartem void 151*2912Sartem libhal_free_string (char *str) 152*2912Sartem { 153*2912Sartem if (str != NULL) { 154*2912Sartem free (str); 155*2912Sartem str = NULL; 156*2912Sartem } 157*2912Sartem } 158*2912Sartem 159*2912Sartem 160*2912Sartem /** 161*2912Sartem * LibHalPropertySet: 162*2912Sartem * 163*2912Sartem * Represents a set of properties. Opaque; use the 164*2912Sartem * libhal_property_set_*() family of functions to access it. 165*2912Sartem */ 166*2912Sartem struct LibHalPropertySet_s { 167*2912Sartem unsigned int num_properties; /**< Number of properties in set */ 168*2912Sartem LibHalProperty *properties_head; 169*2912Sartem /**< Pointer to first property or NULL 170*2912Sartem * if there are no properties */ 171*2912Sartem }; 172*2912Sartem 173*2912Sartem /** 174*2912Sartem * LibHalProperty: 175*2912Sartem * 176*2912Sartem * Represents a property. Opaque. 177*2912Sartem */ 178*2912Sartem struct LibHalProperty_s { 179*2912Sartem int type; /**< Type of property */ 180*2912Sartem char *key; /**< ASCII string */ 181*2912Sartem 182*2912Sartem /** Possible values of the property */ 183*2912Sartem union { 184*2912Sartem char *str_value; /**< UTF-8 zero-terminated string */ 185*2912Sartem dbus_int32_t int_value; 186*2912Sartem /**< 32-bit signed integer */ 187*2912Sartem dbus_uint64_t uint64_value; 188*2912Sartem /**< 64-bit unsigned integer */ 189*2912Sartem double double_value; /**< IEEE754 double precision float */ 190*2912Sartem dbus_bool_t bool_value; 191*2912Sartem /**< Truth value */ 192*2912Sartem 193*2912Sartem char **strlist_value; /**< List of UTF-8 zero-terminated strings */ 194*2912Sartem } v; 195*2912Sartem 196*2912Sartem LibHalProperty *next; /**< Next property or NULL if this is 197*2912Sartem * the last */ 198*2912Sartem }; 199*2912Sartem 200*2912Sartem /** 201*2912Sartem * LibHalContext: 202*2912Sartem * 203*2912Sartem * Context for connection to the HAL daemon. Opaque, use the 204*2912Sartem * libhal_ctx_*() family of functions to access it. 205*2912Sartem */ 206*2912Sartem struct LibHalContext_s { 207*2912Sartem DBusConnection *connection; /**< D-BUS connection */ 208*2912Sartem dbus_bool_t is_initialized; /**< Are we initialised */ 209*2912Sartem dbus_bool_t is_shutdown; /**< Have we been shutdown */ 210*2912Sartem dbus_bool_t cache_enabled; /**< Is the cache enabled */ 211*2912Sartem dbus_bool_t is_direct; /**< Whether the connection to hald is direct */ 212*2912Sartem 213*2912Sartem /** Device added */ 214*2912Sartem LibHalDeviceAdded device_added; 215*2912Sartem 216*2912Sartem /** Device removed */ 217*2912Sartem LibHalDeviceRemoved device_removed; 218*2912Sartem 219*2912Sartem /** Device got a new capability */ 220*2912Sartem LibHalDeviceNewCapability device_new_capability; 221*2912Sartem 222*2912Sartem /** Device got a new capability */ 223*2912Sartem LibHalDeviceLostCapability device_lost_capability; 224*2912Sartem 225*2912Sartem /** A property of a device changed */ 226*2912Sartem LibHalDevicePropertyModified device_property_modified; 227*2912Sartem 228*2912Sartem /** A non-continous event on the device occured */ 229*2912Sartem LibHalDeviceCondition device_condition; 230*2912Sartem 231*2912Sartem void *user_data; /**< User data */ 232*2912Sartem }; 233*2912Sartem 234*2912Sartem /** 235*2912Sartem * libhal_ctx_set_user_data: 236*2912Sartem * @ctx: the context for the connection to hald 237*2912Sartem * @user_data: user data 238*2912Sartem * 239*2912Sartem * Set user data for the context. 240*2912Sartem * 241*2912Sartem * Returns: TRUE if user data was successfully set, FALSE if otherwise 242*2912Sartem */ 243*2912Sartem dbus_bool_t 244*2912Sartem libhal_ctx_set_user_data(LibHalContext *ctx, void *user_data) 245*2912Sartem { 246*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); 247*2912Sartem ctx->user_data = user_data; 248*2912Sartem return TRUE; 249*2912Sartem } 250*2912Sartem 251*2912Sartem /** 252*2912Sartem * libhal_ctx_get_user_data: 253*2912Sartem * @ctx: the context for the connection to hald 254*2912Sartem * 255*2912Sartem * Get user data for the context. 256*2912Sartem * 257*2912Sartem * Returns: opaque pointer stored through libhal_ctx_set_user_data() or NULL if not set. 258*2912Sartem */ 259*2912Sartem void* 260*2912Sartem libhal_ctx_get_user_data(LibHalContext *ctx) 261*2912Sartem { 262*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL); 263*2912Sartem return ctx->user_data; 264*2912Sartem } 265*2912Sartem 266*2912Sartem 267*2912Sartem /** 268*2912Sartem * libhal_property_fill_value_from_variant: 269*2912Sartem * @p: the property to fill in 270*2912Sartem * @var_iter: variant iterator to extract the value from 271*2912Sartem * 272*2912Sartem * Fills in the value for the LibHalProperty given a variant iterator. 273*2912Sartem * 274*2912Sartem * Returns: Whether the value was put in. 275*2912Sartem */ 276*2912Sartem static dbus_bool_t 277*2912Sartem libhal_property_fill_value_from_variant (LibHalProperty *p, DBusMessageIter *var_iter) 278*2912Sartem { 279*2912Sartem DBusMessageIter iter_array; 280*2912Sartem switch (p->type) { 281*2912Sartem case DBUS_TYPE_ARRAY: 282*2912Sartem if (dbus_message_iter_get_element_type (var_iter) != DBUS_TYPE_STRING) 283*2912Sartem return FALSE; 284*2912Sartem 285*2912Sartem dbus_message_iter_recurse (var_iter, &iter_array); 286*2912Sartem p->v.strlist_value = libhal_get_string_array_from_iter (&iter_array, NULL); 287*2912Sartem 288*2912Sartem p->type = LIBHAL_PROPERTY_TYPE_STRLIST; 289*2912Sartem 290*2912Sartem break; 291*2912Sartem case DBUS_TYPE_STRING: 292*2912Sartem { 293*2912Sartem const char *v; 294*2912Sartem 295*2912Sartem dbus_message_iter_get_basic (var_iter, &v); 296*2912Sartem 297*2912Sartem p->v.str_value = strdup (v); 298*2912Sartem if (p->v.str_value == NULL) 299*2912Sartem return FALSE; 300*2912Sartem p->type = LIBHAL_PROPERTY_TYPE_STRING; 301*2912Sartem 302*2912Sartem break; 303*2912Sartem } 304*2912Sartem case DBUS_TYPE_INT32: 305*2912Sartem { 306*2912Sartem dbus_int32_t v; 307*2912Sartem 308*2912Sartem dbus_message_iter_get_basic (var_iter, &v); 309*2912Sartem 310*2912Sartem p->v.int_value = v; 311*2912Sartem p->type = LIBHAL_PROPERTY_TYPE_INT32; 312*2912Sartem 313*2912Sartem break; 314*2912Sartem } 315*2912Sartem case DBUS_TYPE_UINT64: 316*2912Sartem { 317*2912Sartem dbus_uint64_t v; 318*2912Sartem 319*2912Sartem dbus_message_iter_get_basic (var_iter, &v); 320*2912Sartem 321*2912Sartem p->v.uint64_value = v; 322*2912Sartem p->type = LIBHAL_PROPERTY_TYPE_UINT64; 323*2912Sartem 324*2912Sartem break; 325*2912Sartem } 326*2912Sartem case DBUS_TYPE_DOUBLE: 327*2912Sartem { 328*2912Sartem double v; 329*2912Sartem 330*2912Sartem dbus_message_iter_get_basic (var_iter, &v); 331*2912Sartem 332*2912Sartem p->v.double_value = v; 333*2912Sartem p->type = LIBHAL_PROPERTY_TYPE_DOUBLE; 334*2912Sartem 335*2912Sartem break; 336*2912Sartem } 337*2912Sartem case DBUS_TYPE_BOOLEAN: 338*2912Sartem { 339*2912Sartem double v; 340*2912Sartem 341*2912Sartem dbus_message_iter_get_basic (var_iter, &v); 342*2912Sartem 343*2912Sartem p->v.double_value = v; 344*2912Sartem p->type = LIBHAL_PROPERTY_TYPE_BOOLEAN; 345*2912Sartem 346*2912Sartem break; 347*2912Sartem } 348*2912Sartem default: 349*2912Sartem /** @todo report error */ 350*2912Sartem break; 351*2912Sartem } 352*2912Sartem 353*2912Sartem return TRUE; 354*2912Sartem } 355*2912Sartem 356*2912Sartem /** 357*2912Sartem * libhal_device_get_all_properties: 358*2912Sartem * @ctx: the context for the connection to hald 359*2912Sartem * @udi: the Unique id of device 360*2912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL 361*2912Sartem * 362*2912Sartem * Retrieve all the properties on a device. 363*2912Sartem * 364*2912Sartem * Returns: An object represent all properties. Must be freed with libhal_free_property_set(). 365*2912Sartem */ 366*2912Sartem LibHalPropertySet * 367*2912Sartem libhal_device_get_all_properties (LibHalContext *ctx, const char *udi, DBusError *error) 368*2912Sartem { 369*2912Sartem DBusMessage *message; 370*2912Sartem DBusMessage *reply; 371*2912Sartem DBusMessageIter reply_iter; 372*2912Sartem DBusMessageIter dict_iter; 373*2912Sartem LibHalPropertySet *result; 374*2912Sartem LibHalProperty *p_last; 375*2912Sartem DBusError _error; 376*2912Sartem 377*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL); 378*2912Sartem 379*2912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, 380*2912Sartem "org.freedesktop.Hal.Device", 381*2912Sartem "GetAllProperties"); 382*2912Sartem 383*2912Sartem if (message == NULL) { 384*2912Sartem fprintf (stderr, 385*2912Sartem "%s %d : Couldn't allocate D-BUS message\n", 386*2912Sartem __FILE__, __LINE__); 387*2912Sartem return NULL; 388*2912Sartem } 389*2912Sartem 390*2912Sartem dbus_error_init (&_error); 391*2912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection, 392*2912Sartem message, -1, 393*2912Sartem &_error); 394*2912Sartem 395*2912Sartem dbus_move_error (&_error, error); 396*2912Sartem if (error != NULL && dbus_error_is_set (error)) { 397*2912Sartem fprintf (stderr, 398*2912Sartem "%s %d : %s\n", 399*2912Sartem __FILE__, __LINE__, error->message); 400*2912Sartem 401*2912Sartem dbus_message_unref (message); 402*2912Sartem return NULL; 403*2912Sartem } 404*2912Sartem 405*2912Sartem if (reply == NULL) { 406*2912Sartem dbus_message_unref (message); 407*2912Sartem return NULL; 408*2912Sartem } 409*2912Sartem 410*2912Sartem dbus_message_iter_init (reply, &reply_iter); 411*2912Sartem 412*2912Sartem result = malloc (sizeof (LibHalPropertySet)); 413*2912Sartem if (result == NULL) 414*2912Sartem goto oom; 415*2912Sartem /* 416*2912Sartem result->properties = malloc(sizeof(LibHalProperty)*result->num_properties); 417*2912Sartem if( result->properties==NULL ) 418*2912Sartem { 419*2912Sartem /// @todo cleanup 420*2912Sartem return NULL; 421*2912Sartem } 422*2912Sartem */ 423*2912Sartem 424*2912Sartem result->properties_head = NULL; 425*2912Sartem result->num_properties = 0; 426*2912Sartem 427*2912Sartem if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_ARRAY && 428*2912Sartem dbus_message_iter_get_element_type (&reply_iter) != DBUS_TYPE_DICT_ENTRY) { 429*2912Sartem fprintf (stderr, "%s %d : error, expecting an array of dict entries\n", 430*2912Sartem __FILE__, __LINE__); 431*2912Sartem dbus_message_unref (message); 432*2912Sartem dbus_message_unref (reply); 433*2912Sartem return NULL; 434*2912Sartem } 435*2912Sartem 436*2912Sartem dbus_message_iter_recurse (&reply_iter, &dict_iter); 437*2912Sartem 438*2912Sartem p_last = NULL; 439*2912Sartem 440*2912Sartem while (dbus_message_iter_get_arg_type (&dict_iter) == DBUS_TYPE_DICT_ENTRY) 441*2912Sartem { 442*2912Sartem DBusMessageIter dict_entry_iter, var_iter; 443*2912Sartem const char *key; 444*2912Sartem LibHalProperty *p; 445*2912Sartem 446*2912Sartem dbus_message_iter_recurse (&dict_iter, &dict_entry_iter); 447*2912Sartem 448*2912Sartem dbus_message_iter_get_basic (&dict_entry_iter, &key); 449*2912Sartem 450*2912Sartem p = malloc (sizeof (LibHalProperty)); 451*2912Sartem if (p == NULL) 452*2912Sartem goto oom; 453*2912Sartem 454*2912Sartem p->next = NULL; 455*2912Sartem 456*2912Sartem if (result->num_properties == 0) 457*2912Sartem result->properties_head = p; 458*2912Sartem 459*2912Sartem if (p_last != NULL) 460*2912Sartem p_last->next = p; 461*2912Sartem 462*2912Sartem p_last = p; 463*2912Sartem 464*2912Sartem p->key = strdup (key); 465*2912Sartem if (p->key == NULL) 466*2912Sartem goto oom; 467*2912Sartem 468*2912Sartem dbus_message_iter_next (&dict_entry_iter); 469*2912Sartem 470*2912Sartem dbus_message_iter_recurse (&dict_entry_iter, &var_iter); 471*2912Sartem 472*2912Sartem 473*2912Sartem p->type = dbus_message_iter_get_arg_type (&var_iter); 474*2912Sartem 475*2912Sartem result->num_properties++; 476*2912Sartem 477*2912Sartem if(!libhal_property_fill_value_from_variant (p, &var_iter)) 478*2912Sartem goto oom; 479*2912Sartem 480*2912Sartem dbus_message_iter_next (&dict_iter); 481*2912Sartem } 482*2912Sartem 483*2912Sartem dbus_message_unref (message); 484*2912Sartem dbus_message_unref (reply); 485*2912Sartem 486*2912Sartem return result; 487*2912Sartem 488*2912Sartem oom: 489*2912Sartem fprintf (stderr, 490*2912Sartem "%s %d : error allocating memory\n", 491*2912Sartem __FILE__, __LINE__); 492*2912Sartem /** @todo FIXME cleanup */ 493*2912Sartem return NULL; 494*2912Sartem } 495*2912Sartem 496*2912Sartem /** 497*2912Sartem * libhal_free_property_set: 498*2912Sartem * @set: property-set to free 499*2912Sartem * 500*2912Sartem * Free a property set earlier obtained with libhal_device_get_all_properties(). 501*2912Sartem */ 502*2912Sartem void 503*2912Sartem libhal_free_property_set (LibHalPropertySet * set) 504*2912Sartem { 505*2912Sartem LibHalProperty *p; 506*2912Sartem LibHalProperty *q; 507*2912Sartem 508*2912Sartem if (set == NULL) 509*2912Sartem return; 510*2912Sartem 511*2912Sartem for (p = set->properties_head; p != NULL; p = q) { 512*2912Sartem free (p->key); 513*2912Sartem if (p->type == DBUS_TYPE_STRING) 514*2912Sartem free (p->v.str_value); 515*2912Sartem if (p->type == LIBHAL_PROPERTY_TYPE_STRLIST) 516*2912Sartem libhal_free_string_array (p->v.strlist_value); 517*2912Sartem q = p->next; 518*2912Sartem free (p); 519*2912Sartem } 520*2912Sartem free (set); 521*2912Sartem } 522*2912Sartem 523*2912Sartem /** 524*2912Sartem * libhal_property_set_get_num_elems: 525*2912Sartem * @set: property set to consider 526*2912Sartem * 527*2912Sartem * Get the number of properties in a property set. 528*2912Sartem * 529*2912Sartem * Returns: number of properties in given property set 530*2912Sartem */ 531*2912Sartem unsigned int 532*2912Sartem libhal_property_set_get_num_elems (LibHalPropertySet *set) 533*2912Sartem { 534*2912Sartem unsigned int num_elems; 535*2912Sartem LibHalProperty *p; 536*2912Sartem 537*2912Sartem if (set == NULL) 538*2912Sartem return 0; 539*2912Sartem 540*2912Sartem num_elems = 0; 541*2912Sartem for (p = set->properties_head; p != NULL; p = p->next) 542*2912Sartem num_elems++; 543*2912Sartem 544*2912Sartem return num_elems; 545*2912Sartem } 546*2912Sartem 547*2912Sartem 548*2912Sartem /** 549*2912Sartem * libhal_psi_init: 550*2912Sartem * @iter: iterator object 551*2912Sartem * @set: property set to iterate over 552*2912Sartem * 553*2912Sartem * Initialize a property set iterator. 554*2912Sartem * 555*2912Sartem */ 556*2912Sartem void 557*2912Sartem libhal_psi_init (LibHalPropertySetIterator * iter, LibHalPropertySet * set) 558*2912Sartem { 559*2912Sartem if (set == NULL) 560*2912Sartem return; 561*2912Sartem 562*2912Sartem iter->set = set; 563*2912Sartem iter->idx = 0; 564*2912Sartem iter->cur_prop = set->properties_head; 565*2912Sartem } 566*2912Sartem 567*2912Sartem 568*2912Sartem /** 569*2912Sartem * libhal_psi_has_more: 570*2912Sartem * @iter: iterator object 571*2912Sartem * 572*2912Sartem * Determine whether there are more properties to iterate over. 573*2912Sartem * 574*2912Sartem * Returns: TRUE if there are more properties, FALSE otherwise. 575*2912Sartem */ 576*2912Sartem dbus_bool_t 577*2912Sartem libhal_psi_has_more (LibHalPropertySetIterator * iter) 578*2912Sartem { 579*2912Sartem return iter->idx < iter->set->num_properties; 580*2912Sartem } 581*2912Sartem 582*2912Sartem /** 583*2912Sartem * libhal_psi_next: 584*2912Sartem * @iter: iterator object 585*2912Sartem * 586*2912Sartem * Advance iterator to next property. 587*2912Sartem */ 588*2912Sartem void 589*2912Sartem libhal_psi_next (LibHalPropertySetIterator * iter) 590*2912Sartem { 591*2912Sartem iter->idx++; 592*2912Sartem iter->cur_prop = iter->cur_prop->next; 593*2912Sartem } 594*2912Sartem 595*2912Sartem /** 596*2912Sartem * libhal_psi_get_type: 597*2912Sartem * @iter: iterator object 598*2912Sartem * 599*2912Sartem * Get type of property. 600*2912Sartem * 601*2912Sartem * Returns: the property type at the iterator's position 602*2912Sartem */ 603*2912Sartem LibHalPropertyType 604*2912Sartem libhal_psi_get_type (LibHalPropertySetIterator * iter) 605*2912Sartem { 606*2912Sartem return iter->cur_prop->type; 607*2912Sartem } 608*2912Sartem 609*2912Sartem /** 610*2912Sartem * libhal_psi_get_key: 611*2912Sartem * @iter: iterator object 612*2912Sartem * 613*2912Sartem * Get the key of a property. 614*2912Sartem * 615*2912Sartem * Returns: ASCII nul-terminated string. This pointer is only valid 616*2912Sartem * until libhal_free_property_set() is invoked on the property set 617*2912Sartem * this property belongs to. 618*2912Sartem */ 619*2912Sartem char * 620*2912Sartem libhal_psi_get_key (LibHalPropertySetIterator * iter) 621*2912Sartem { 622*2912Sartem return iter->cur_prop->key; 623*2912Sartem } 624*2912Sartem 625*2912Sartem /** 626*2912Sartem * libhal_psi_get_string: 627*2912Sartem * @iter: iterator object 628*2912Sartem * 629*2912Sartem * Get the value of a property of type string. 630*2912Sartem * 631*2912Sartem * Returns: UTF8 nul-terminated string. This pointer is only valid 632*2912Sartem * until libhal_free_property_set() is invoked on the property set 633*2912Sartem * this property belongs to. 634*2912Sartem */ 635*2912Sartem char * 636*2912Sartem libhal_psi_get_string (LibHalPropertySetIterator * iter) 637*2912Sartem { 638*2912Sartem return iter->cur_prop->v.str_value; 639*2912Sartem } 640*2912Sartem 641*2912Sartem /** 642*2912Sartem * libhal_psi_get_int: 643*2912Sartem * @iter: iterator object 644*2912Sartem * 645*2912Sartem * Get the value of a property of type signed integer. 646*2912Sartem * 647*2912Sartem * Returns: property value (32-bit signed integer) 648*2912Sartem */ 649*2912Sartem dbus_int32_t 650*2912Sartem libhal_psi_get_int (LibHalPropertySetIterator * iter) 651*2912Sartem { 652*2912Sartem return iter->cur_prop->v.int_value; 653*2912Sartem } 654*2912Sartem 655*2912Sartem /** 656*2912Sartem * libhal_psi_get_uint64: 657*2912Sartem * @iter: iterator object 658*2912Sartem * 659*2912Sartem * Get the value of a property of type unsigned integer. 660*2912Sartem * 661*2912Sartem * Returns: property value (64-bit unsigned integer) 662*2912Sartem */ 663*2912Sartem dbus_uint64_t 664*2912Sartem libhal_psi_get_uint64 (LibHalPropertySetIterator * iter) 665*2912Sartem { 666*2912Sartem return iter->cur_prop->v.uint64_value; 667*2912Sartem } 668*2912Sartem 669*2912Sartem /** 670*2912Sartem * libhal_psi_get_double: 671*2912Sartem * @iter: iterator object 672*2912Sartem * 673*2912Sartem * Get the value of a property of type double. 674*2912Sartem * 675*2912Sartem * Returns: property value (IEEE754 double precision float) 676*2912Sartem */ 677*2912Sartem double 678*2912Sartem libhal_psi_get_double (LibHalPropertySetIterator * iter) 679*2912Sartem { 680*2912Sartem return iter->cur_prop->v.double_value; 681*2912Sartem } 682*2912Sartem 683*2912Sartem /** 684*2912Sartem * libhal_psi_get_bool: 685*2912Sartem * @iter: iterator object 686*2912Sartem * 687*2912Sartem * Get the value of a property of type bool. 688*2912Sartem * 689*2912Sartem * Returns: property value (bool) 690*2912Sartem */ 691*2912Sartem dbus_bool_t 692*2912Sartem libhal_psi_get_bool (LibHalPropertySetIterator * iter) 693*2912Sartem { 694*2912Sartem return iter->cur_prop->v.bool_value; 695*2912Sartem } 696*2912Sartem 697*2912Sartem /** 698*2912Sartem * libhal_psi_get_strlist: 699*2912Sartem * @iter: iterator object 700*2912Sartem * 701*2912Sartem * Get the value of a property of type string list. 702*2912Sartem * 703*2912Sartem * Returns: pointer to array of strings 704*2912Sartem */ 705*2912Sartem char ** 706*2912Sartem libhal_psi_get_strlist (LibHalPropertySetIterator * iter) 707*2912Sartem { 708*2912Sartem return iter->cur_prop->v.strlist_value; 709*2912Sartem } 710*2912Sartem 711*2912Sartem 712*2912Sartem static DBusHandlerResult 713*2912Sartem filter_func (DBusConnection * connection, 714*2912Sartem DBusMessage * message, void *user_data) 715*2912Sartem { 716*2912Sartem const char *object_path; 717*2912Sartem DBusError error; 718*2912Sartem LibHalContext *ctx = (LibHalContext *) user_data; 719*2912Sartem 720*2912Sartem if (ctx->is_shutdown) 721*2912Sartem return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 722*2912Sartem 723*2912Sartem dbus_error_init (&error); 724*2912Sartem 725*2912Sartem object_path = dbus_message_get_path (message); 726*2912Sartem 727*2912Sartem /*printf("*** in filter_func, object_path=%s\n", object_path);*/ 728*2912Sartem 729*2912Sartem if (dbus_message_is_signal (message, "org.freedesktop.Hal.Manager", 730*2912Sartem "DeviceAdded")) { 731*2912Sartem char *udi; 732*2912Sartem if (dbus_message_get_args (message, &error, 733*2912Sartem DBUS_TYPE_STRING, &udi, 734*2912Sartem DBUS_TYPE_INVALID)) { 735*2912Sartem if (ctx->device_added != NULL) { 736*2912Sartem ctx->device_added (ctx, udi); 737*2912Sartem } 738*2912Sartem } else { 739*2912Sartem LIBHAL_FREE_DBUS_ERROR(&error); 740*2912Sartem } 741*2912Sartem return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 742*2912Sartem } else if (dbus_message_is_signal (message, "org.freedesktop.Hal.Manager", "DeviceRemoved")) { 743*2912Sartem char *udi; 744*2912Sartem if (dbus_message_get_args (message, &error, 745*2912Sartem DBUS_TYPE_STRING, &udi, 746*2912Sartem DBUS_TYPE_INVALID)) { 747*2912Sartem if (ctx->device_removed != NULL) { 748*2912Sartem ctx->device_removed (ctx, udi); 749*2912Sartem } 750*2912Sartem } else { 751*2912Sartem LIBHAL_FREE_DBUS_ERROR(&error); 752*2912Sartem } 753*2912Sartem return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 754*2912Sartem } else if (dbus_message_is_signal (message, "org.freedesktop.Hal.Manager","NewCapability")) { 755*2912Sartem char *udi; 756*2912Sartem char *capability; 757*2912Sartem if (dbus_message_get_args (message, &error, 758*2912Sartem DBUS_TYPE_STRING, &udi, 759*2912Sartem DBUS_TYPE_STRING, &capability, 760*2912Sartem DBUS_TYPE_INVALID)) { 761*2912Sartem if (ctx->device_new_capability != NULL) { 762*2912Sartem ctx->device_new_capability (ctx, udi, capability); 763*2912Sartem } 764*2912Sartem } else { 765*2912Sartem LIBHAL_FREE_DBUS_ERROR(&error); 766*2912Sartem } 767*2912Sartem return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 768*2912Sartem } else if (dbus_message_is_signal (message, "org.freedesktop.Hal.Device", "Condition")) { 769*2912Sartem char *condition_name; 770*2912Sartem char *condition_detail; 771*2912Sartem if (dbus_message_get_args (message, &error, 772*2912Sartem DBUS_TYPE_STRING, &condition_name, 773*2912Sartem DBUS_TYPE_STRING, &condition_detail, 774*2912Sartem DBUS_TYPE_INVALID)) { 775*2912Sartem if (ctx->device_condition != NULL) { 776*2912Sartem ctx->device_condition (ctx, object_path, condition_name, condition_detail); 777*2912Sartem } 778*2912Sartem } else { 779*2912Sartem LIBHAL_FREE_DBUS_ERROR(&error); 780*2912Sartem } 781*2912Sartem return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 782*2912Sartem } else if (dbus_message_is_signal (message, "org.freedesktop.Hal.Device", "PropertyModified")) { 783*2912Sartem if (ctx->device_property_modified != NULL) { 784*2912Sartem int i; 785*2912Sartem char *key; 786*2912Sartem dbus_bool_t removed; 787*2912Sartem dbus_bool_t added; 788*2912Sartem int num_modifications; 789*2912Sartem DBusMessageIter iter; 790*2912Sartem DBusMessageIter iter_array; 791*2912Sartem 792*2912Sartem dbus_message_iter_init (message, &iter); 793*2912Sartem dbus_message_iter_get_basic (&iter, &num_modifications); 794*2912Sartem dbus_message_iter_next (&iter); 795*2912Sartem 796*2912Sartem dbus_message_iter_recurse (&iter, &iter_array); 797*2912Sartem 798*2912Sartem for (i = 0; i < num_modifications; i++) { 799*2912Sartem DBusMessageIter iter_struct; 800*2912Sartem 801*2912Sartem dbus_message_iter_recurse (&iter_array, &iter_struct); 802*2912Sartem 803*2912Sartem dbus_message_iter_get_basic (&iter_struct, &key); 804*2912Sartem dbus_message_iter_next (&iter_struct); 805*2912Sartem dbus_message_iter_get_basic (&iter_struct, &removed); 806*2912Sartem dbus_message_iter_next (&iter_struct); 807*2912Sartem dbus_message_iter_get_basic (&iter_struct, &added); 808*2912Sartem 809*2912Sartem ctx->device_property_modified (ctx, 810*2912Sartem object_path, 811*2912Sartem key, removed, 812*2912Sartem added); 813*2912Sartem 814*2912Sartem dbus_message_iter_next (&iter_array); 815*2912Sartem } 816*2912Sartem 817*2912Sartem } 818*2912Sartem return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 819*2912Sartem } 820*2912Sartem 821*2912Sartem return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 822*2912Sartem } 823*2912Sartem 824*2912Sartem /* for i18n purposes */ 825*2912Sartem static dbus_bool_t libhal_already_initialized_once = FALSE; 826*2912Sartem 827*2912Sartem 828*2912Sartem /** 829*2912Sartem * libhal_get_all_devices: 830*2912Sartem * @ctx: the context for the connection to hald 831*2912Sartem * @num_devices: the number of devices will be stored here 832*2912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL 833*2912Sartem * 834*2912Sartem * Get all devices in the Global Device List (GDL). 835*2912Sartem * 836*2912Sartem * Returns: An array of device identifiers terminated with NULL. It is 837*2912Sartem * the responsibility of the caller to free with 838*2912Sartem * libhal_free_string_array(). If an error occurs NULL is returned. 839*2912Sartem */ 840*2912Sartem char ** 841*2912Sartem libhal_get_all_devices (LibHalContext *ctx, int *num_devices, DBusError *error) 842*2912Sartem { 843*2912Sartem DBusMessage *message; 844*2912Sartem DBusMessage *reply; 845*2912Sartem DBusMessageIter iter_array, reply_iter; 846*2912Sartem char **hal_device_names; 847*2912Sartem DBusError _error; 848*2912Sartem 849*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL); 850*2912Sartem 851*2912Sartem *num_devices = 0; 852*2912Sartem 853*2912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", 854*2912Sartem "/org/freedesktop/Hal/Manager", 855*2912Sartem "org.freedesktop.Hal.Manager", 856*2912Sartem "GetAllDevices"); 857*2912Sartem if (message == NULL) { 858*2912Sartem fprintf (stderr, "%s %d : Could not allocate D-BUS message\n", __FILE__, __LINE__); 859*2912Sartem return NULL; 860*2912Sartem } 861*2912Sartem 862*2912Sartem dbus_error_init (&_error); 863*2912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection, message, -1, &_error); 864*2912Sartem 865*2912Sartem dbus_move_error (&_error, error); 866*2912Sartem if (error != NULL && dbus_error_is_set (error)) { 867*2912Sartem dbus_message_unref (message); 868*2912Sartem return NULL; 869*2912Sartem } 870*2912Sartem if (reply == NULL) { 871*2912Sartem dbus_message_unref (message); 872*2912Sartem return NULL; 873*2912Sartem } 874*2912Sartem 875*2912Sartem /* now analyze reply */ 876*2912Sartem dbus_message_iter_init (reply, &reply_iter); 877*2912Sartem 878*2912Sartem if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_ARRAY) { 879*2912Sartem fprintf (stderr, "%s %d : wrong reply from hald. Expecting an array.\n", __FILE__, __LINE__); 880*2912Sartem return NULL; 881*2912Sartem } 882*2912Sartem 883*2912Sartem dbus_message_iter_recurse (&reply_iter, &iter_array); 884*2912Sartem 885*2912Sartem hal_device_names = libhal_get_string_array_from_iter (&iter_array, num_devices); 886*2912Sartem 887*2912Sartem dbus_message_unref (reply); 888*2912Sartem dbus_message_unref (message); 889*2912Sartem 890*2912Sartem return hal_device_names; 891*2912Sartem } 892*2912Sartem 893*2912Sartem /** 894*2912Sartem * libhal_device_get_property_type: 895*2912Sartem * @ctx: the context for the connection to hald 896*2912Sartem * @udi: the Unique Device Id 897*2912Sartem * @key: name of the property 898*2912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL 899*2912Sartem * 900*2912Sartem * Query a property type of a device. 901*2912Sartem * 902*2912Sartem * Returns: A LibHalPropertyType. LIBHAL_PROPERTY_TYPE_INVALID is 903*2912Sartem * return if the property doesn't exist. 904*2912Sartem */ 905*2912Sartem LibHalPropertyType 906*2912Sartem libhal_device_get_property_type (LibHalContext *ctx, const char *udi, const char *key, DBusError *error) 907*2912Sartem { 908*2912Sartem DBusMessage *message; 909*2912Sartem DBusMessage *reply; 910*2912Sartem DBusMessageIter iter, reply_iter; 911*2912Sartem int type; 912*2912Sartem DBusError _error; 913*2912Sartem 914*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, LIBHAL_PROPERTY_TYPE_INVALID); /* or return NULL? */ 915*2912Sartem 916*2912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, 917*2912Sartem "org.freedesktop.Hal.Device", 918*2912Sartem "GetPropertyType"); 919*2912Sartem if (message == NULL) { 920*2912Sartem fprintf (stderr, "%s %d : Couldn't allocate D-BUS message\n", __FILE__, __LINE__); 921*2912Sartem return LIBHAL_PROPERTY_TYPE_INVALID; 922*2912Sartem } 923*2912Sartem 924*2912Sartem dbus_message_iter_init_append (message, &iter); 925*2912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key); 926*2912Sartem 927*2912Sartem dbus_error_init (&_error); 928*2912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection, 929*2912Sartem message, -1, 930*2912Sartem &_error); 931*2912Sartem 932*2912Sartem dbus_move_error (&_error, error); 933*2912Sartem if (error != NULL && dbus_error_is_set (error)) { 934*2912Sartem dbus_message_unref (message); 935*2912Sartem return LIBHAL_PROPERTY_TYPE_INVALID; 936*2912Sartem } 937*2912Sartem if (reply == NULL) { 938*2912Sartem dbus_message_unref (message); 939*2912Sartem return LIBHAL_PROPERTY_TYPE_INVALID; 940*2912Sartem } 941*2912Sartem 942*2912Sartem dbus_message_iter_init (reply, &reply_iter); 943*2912Sartem dbus_message_iter_get_basic (&reply_iter, &type); 944*2912Sartem 945*2912Sartem dbus_message_unref (message); 946*2912Sartem dbus_message_unref (reply); 947*2912Sartem 948*2912Sartem return type; 949*2912Sartem } 950*2912Sartem 951*2912Sartem /** 952*2912Sartem * libhal_device_get_property_strlist: 953*2912Sartem * @ctx: the context for the connection to hald 954*2912Sartem * @udi: unique Device Id 955*2912Sartem * @key: name of the property 956*2912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL 957*2912Sartem * 958*2912Sartem * Get the value of a property of type string list. 959*2912Sartem * 960*2912Sartem * Returns: Array of pointers to UTF8 nul-terminated strings 961*2912Sartem * terminated by NULL. The caller is responsible for freeing this 962*2912Sartem * string array with the function libhal_free_string_array(). Returns 963*2912Sartem * NULL if the property didn't exist or we are OOM 964*2912Sartem */ 965*2912Sartem char ** 966*2912Sartem libhal_device_get_property_strlist (LibHalContext *ctx, const char *udi, const char *key, DBusError *error) 967*2912Sartem { 968*2912Sartem DBusMessage *message; 969*2912Sartem DBusMessage *reply; 970*2912Sartem DBusMessageIter iter, iter_array, reply_iter; 971*2912Sartem char **our_strings; 972*2912Sartem DBusError _error; 973*2912Sartem 974*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL); 975*2912Sartem 976*2912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, 977*2912Sartem "org.freedesktop.Hal.Device", 978*2912Sartem "GetPropertyStringList"); 979*2912Sartem if (message == NULL) { 980*2912Sartem fprintf (stderr, 981*2912Sartem "%s %d : Couldn't allocate D-BUS message\n", 982*2912Sartem __FILE__, __LINE__); 983*2912Sartem return NULL; 984*2912Sartem } 985*2912Sartem 986*2912Sartem dbus_message_iter_init_append (message, &iter); 987*2912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key); 988*2912Sartem 989*2912Sartem dbus_error_init (&_error); 990*2912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection, 991*2912Sartem message, -1, 992*2912Sartem &_error); 993*2912Sartem 994*2912Sartem dbus_move_error (&_error, error); 995*2912Sartem if (error != NULL && dbus_error_is_set (error)) { 996*2912Sartem dbus_message_unref (message); 997*2912Sartem return NULL; 998*2912Sartem } 999*2912Sartem if (reply == NULL) { 1000*2912Sartem dbus_message_unref (message); 1001*2912Sartem return NULL; 1002*2912Sartem } 1003*2912Sartem /* now analyse reply */ 1004*2912Sartem dbus_message_iter_init (reply, &reply_iter); 1005*2912Sartem 1006*2912Sartem if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_ARRAY) { 1007*2912Sartem fprintf (stderr, "%s %d : wrong reply from hald. Expecting an array.\n", __FILE__, __LINE__); 1008*2912Sartem return NULL; 1009*2912Sartem } 1010*2912Sartem 1011*2912Sartem dbus_message_iter_recurse (&reply_iter, &iter_array); 1012*2912Sartem 1013*2912Sartem our_strings = libhal_get_string_array_from_iter (&iter_array, NULL); 1014*2912Sartem 1015*2912Sartem dbus_message_unref (reply); 1016*2912Sartem dbus_message_unref (message); 1017*2912Sartem 1018*2912Sartem return our_strings; 1019*2912Sartem } 1020*2912Sartem 1021*2912Sartem /** 1022*2912Sartem * libhal_device_get_property_string: 1023*2912Sartem * @ctx: the context for the connection to hald 1024*2912Sartem * @udi: the Unique Device Id 1025*2912Sartem * @key: the name of the property 1026*2912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL 1027*2912Sartem * 1028*2912Sartem * Get the value of a property of type string. 1029*2912Sartem * 1030*2912Sartem * Returns: UTF8 nul-terminated string. The caller is responsible for 1031*2912Sartem * freeing this string with the function libhal_free_string(). Returns 1032*2912Sartem * NULL if the property didn't exist or we are OOM. 1033*2912Sartem */ 1034*2912Sartem char * 1035*2912Sartem libhal_device_get_property_string (LibHalContext *ctx, 1036*2912Sartem const char *udi, const char *key, DBusError *error) 1037*2912Sartem { 1038*2912Sartem DBusMessage *message; 1039*2912Sartem DBusMessage *reply; 1040*2912Sartem DBusMessageIter iter, reply_iter; 1041*2912Sartem char *value; 1042*2912Sartem char *dbus_str; 1043*2912Sartem DBusError _error; 1044*2912Sartem 1045*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL); 1046*2912Sartem 1047*2912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, 1048*2912Sartem "org.freedesktop.Hal.Device", 1049*2912Sartem "GetPropertyString"); 1050*2912Sartem 1051*2912Sartem if (message == NULL) { 1052*2912Sartem fprintf (stderr, 1053*2912Sartem "%s %d : Couldn't allocate D-BUS message\n", 1054*2912Sartem __FILE__, __LINE__); 1055*2912Sartem return NULL; 1056*2912Sartem } 1057*2912Sartem 1058*2912Sartem dbus_message_iter_init_append (message, &iter); 1059*2912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key); 1060*2912Sartem 1061*2912Sartem dbus_error_init (&_error); 1062*2912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection, 1063*2912Sartem message, -1, 1064*2912Sartem &_error); 1065*2912Sartem 1066*2912Sartem dbus_move_error (&_error, error); 1067*2912Sartem if (error != NULL && dbus_error_is_set (error)) { 1068*2912Sartem dbus_message_unref (message); 1069*2912Sartem return NULL; 1070*2912Sartem } 1071*2912Sartem if (reply == NULL) { 1072*2912Sartem dbus_message_unref (message); 1073*2912Sartem return NULL; 1074*2912Sartem } 1075*2912Sartem 1076*2912Sartem dbus_message_iter_init (reply, &reply_iter); 1077*2912Sartem 1078*2912Sartem /* now analyze reply */ 1079*2912Sartem if (dbus_message_iter_get_arg_type (&reply_iter) != 1080*2912Sartem DBUS_TYPE_STRING) { 1081*2912Sartem dbus_message_unref (message); 1082*2912Sartem dbus_message_unref (reply); 1083*2912Sartem return NULL; 1084*2912Sartem } 1085*2912Sartem 1086*2912Sartem dbus_message_iter_get_basic (&reply_iter, &dbus_str); 1087*2912Sartem value = (char *) ((dbus_str != NULL) ? strdup (dbus_str) : NULL); 1088*2912Sartem if (value == NULL) { 1089*2912Sartem fprintf (stderr, "%s %d : error allocating memory\n", 1090*2912Sartem __FILE__, __LINE__); 1091*2912Sartem /** @todo FIXME cleanup */ 1092*2912Sartem return NULL; 1093*2912Sartem } 1094*2912Sartem 1095*2912Sartem dbus_message_unref (message); 1096*2912Sartem dbus_message_unref (reply); 1097*2912Sartem return value; 1098*2912Sartem } 1099*2912Sartem 1100*2912Sartem /** 1101*2912Sartem * libhal_device_get_property_int: 1102*2912Sartem * @ctx: the context for the connection to hald 1103*2912Sartem * @udi: the Unique Device Id 1104*2912Sartem * @key: name of the property 1105*2912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL 1106*2912Sartem * 1107*2912Sartem * Get the value of a property of type integer. 1108*2912Sartem * 1109*2912Sartem * Returns: Property value (32-bit signed integer) 1110*2912Sartem */ 1111*2912Sartem dbus_int32_t 1112*2912Sartem libhal_device_get_property_int (LibHalContext *ctx, 1113*2912Sartem const char *udi, const char *key, DBusError *error) 1114*2912Sartem { 1115*2912Sartem DBusMessage *message; 1116*2912Sartem DBusMessage *reply; 1117*2912Sartem DBusMessageIter iter, reply_iter; 1118*2912Sartem dbus_int32_t value; 1119*2912Sartem DBusError _error; 1120*2912Sartem 1121*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, -1); 1122*2912Sartem 1123*2912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, 1124*2912Sartem "org.freedesktop.Hal.Device", 1125*2912Sartem "GetPropertyInteger"); 1126*2912Sartem if (message == NULL) { 1127*2912Sartem fprintf (stderr, 1128*2912Sartem "%s %d : Couldn't allocate D-BUS message\n", 1129*2912Sartem __FILE__, __LINE__); 1130*2912Sartem return -1; 1131*2912Sartem } 1132*2912Sartem 1133*2912Sartem dbus_message_iter_init_append (message, &iter); 1134*2912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key); 1135*2912Sartem 1136*2912Sartem dbus_error_init (&_error); 1137*2912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection, 1138*2912Sartem message, -1, 1139*2912Sartem &_error); 1140*2912Sartem 1141*2912Sartem dbus_move_error (&_error, error); 1142*2912Sartem if (error != NULL && dbus_error_is_set (error)) { 1143*2912Sartem dbus_message_unref (message); 1144*2912Sartem return -1; 1145*2912Sartem } 1146*2912Sartem if (reply == NULL) { 1147*2912Sartem dbus_message_unref (message); 1148*2912Sartem return -1; 1149*2912Sartem } 1150*2912Sartem 1151*2912Sartem dbus_message_iter_init (reply, &reply_iter); 1152*2912Sartem 1153*2912Sartem /* now analyze reply */ 1154*2912Sartem if (dbus_message_iter_get_arg_type (&reply_iter) != 1155*2912Sartem DBUS_TYPE_INT32) { 1156*2912Sartem fprintf (stderr, 1157*2912Sartem "%s %d : property '%s' for device '%s' is not " 1158*2912Sartem "of type integer\n", __FILE__, __LINE__, key, 1159*2912Sartem udi); 1160*2912Sartem dbus_message_unref (message); 1161*2912Sartem dbus_message_unref (reply); 1162*2912Sartem return -1; 1163*2912Sartem } 1164*2912Sartem dbus_message_iter_get_basic (&reply_iter, &value); 1165*2912Sartem 1166*2912Sartem dbus_message_unref (message); 1167*2912Sartem dbus_message_unref (reply); 1168*2912Sartem return value; 1169*2912Sartem } 1170*2912Sartem 1171*2912Sartem /** 1172*2912Sartem * libhal_device_get_property_uint64: 1173*2912Sartem * @ctx: the context for the connection to hald 1174*2912Sartem * @udi: the Unique Device Id 1175*2912Sartem * @key: name of the property 1176*2912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL 1177*2912Sartem * 1178*2912Sartem * Get the value of a property of type signed integer. 1179*2912Sartem * 1180*2912Sartem * Returns: Property value (64-bit unsigned integer) 1181*2912Sartem */ 1182*2912Sartem dbus_uint64_t 1183*2912Sartem libhal_device_get_property_uint64 (LibHalContext *ctx, 1184*2912Sartem const char *udi, const char *key, DBusError *error) 1185*2912Sartem { 1186*2912Sartem DBusMessage *message; 1187*2912Sartem DBusMessage *reply; 1188*2912Sartem DBusMessageIter iter, reply_iter; 1189*2912Sartem dbus_uint64_t value; 1190*2912Sartem DBusError _error; 1191*2912Sartem 1192*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, -1); 1193*2912Sartem 1194*2912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, 1195*2912Sartem "org.freedesktop.Hal.Device", 1196*2912Sartem "GetPropertyInteger"); 1197*2912Sartem if (message == NULL) { 1198*2912Sartem fprintf (stderr, 1199*2912Sartem "%s %d : Couldn't allocate D-BUS message\n", 1200*2912Sartem __FILE__, __LINE__); 1201*2912Sartem return -1; 1202*2912Sartem } 1203*2912Sartem 1204*2912Sartem dbus_message_iter_init_append (message, &iter); 1205*2912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key); 1206*2912Sartem 1207*2912Sartem dbus_error_init (&_error); 1208*2912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection, 1209*2912Sartem message, -1, 1210*2912Sartem &_error); 1211*2912Sartem 1212*2912Sartem dbus_move_error (&_error, error); 1213*2912Sartem if (error != NULL && dbus_error_is_set (error)) { 1214*2912Sartem dbus_message_unref (message); 1215*2912Sartem return -1; 1216*2912Sartem } 1217*2912Sartem if (reply == NULL) { 1218*2912Sartem dbus_message_unref (message); 1219*2912Sartem return -1; 1220*2912Sartem } 1221*2912Sartem 1222*2912Sartem dbus_message_iter_init (reply, &reply_iter); 1223*2912Sartem /* now analyze reply */ 1224*2912Sartem if (dbus_message_iter_get_arg_type (&reply_iter) != 1225*2912Sartem DBUS_TYPE_UINT64) { 1226*2912Sartem fprintf (stderr, 1227*2912Sartem "%s %d : property '%s' for device '%s' is not " 1228*2912Sartem "of type integer\n", __FILE__, __LINE__, key, 1229*2912Sartem udi); 1230*2912Sartem dbus_message_unref (message); 1231*2912Sartem dbus_message_unref (reply); 1232*2912Sartem return -1; 1233*2912Sartem } 1234*2912Sartem dbus_message_iter_get_basic (&reply_iter, &value); 1235*2912Sartem 1236*2912Sartem dbus_message_unref (message); 1237*2912Sartem dbus_message_unref (reply); 1238*2912Sartem return value; 1239*2912Sartem } 1240*2912Sartem 1241*2912Sartem /** 1242*2912Sartem * libhal_device_get_property_double: 1243*2912Sartem * @ctx: the context for the connection to hald 1244*2912Sartem * @udi: the Unique Device Id 1245*2912Sartem * @key: name of the property 1246*2912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL 1247*2912Sartem * 1248*2912Sartem * Get the value of a property of type double. 1249*2912Sartem * 1250*2912Sartem * Returns: Property value (IEEE754 double precision float) 1251*2912Sartem */ 1252*2912Sartem double 1253*2912Sartem libhal_device_get_property_double (LibHalContext *ctx, 1254*2912Sartem const char *udi, const char *key, DBusError *error) 1255*2912Sartem { 1256*2912Sartem DBusMessage *message; 1257*2912Sartem DBusMessage *reply; 1258*2912Sartem DBusMessageIter iter, reply_iter; 1259*2912Sartem double value; 1260*2912Sartem DBusError _error; 1261*2912Sartem 1262*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, -1.0); 1263*2912Sartem 1264*2912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, 1265*2912Sartem "org.freedesktop.Hal.Device", 1266*2912Sartem "GetPropertyDouble"); 1267*2912Sartem if (message == NULL) { 1268*2912Sartem fprintf (stderr, 1269*2912Sartem "%s %d : Couldn't allocate D-BUS message\n", 1270*2912Sartem __FILE__, __LINE__); 1271*2912Sartem return -1.0f; 1272*2912Sartem } 1273*2912Sartem 1274*2912Sartem dbus_message_iter_init_append (message, &iter); 1275*2912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key); 1276*2912Sartem 1277*2912Sartem dbus_error_init (&_error); 1278*2912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection, 1279*2912Sartem message, -1, 1280*2912Sartem &_error); 1281*2912Sartem 1282*2912Sartem dbus_move_error (&_error, error); 1283*2912Sartem if (error != NULL && dbus_error_is_set (error)) { 1284*2912Sartem dbus_message_unref (message); 1285*2912Sartem return -1.0f; 1286*2912Sartem } 1287*2912Sartem if (reply == NULL) { 1288*2912Sartem dbus_message_unref (message); 1289*2912Sartem return -1.0f; 1290*2912Sartem } 1291*2912Sartem 1292*2912Sartem dbus_message_iter_init (reply, &reply_iter); 1293*2912Sartem 1294*2912Sartem /* now analyze reply */ 1295*2912Sartem if (dbus_message_iter_get_arg_type (&reply_iter) != 1296*2912Sartem DBUS_TYPE_DOUBLE) { 1297*2912Sartem fprintf (stderr, 1298*2912Sartem "%s %d : property '%s' for device '%s' is not " 1299*2912Sartem "of type double\n", __FILE__, __LINE__, key, udi); 1300*2912Sartem dbus_message_unref (message); 1301*2912Sartem dbus_message_unref (reply); 1302*2912Sartem return -1.0f; 1303*2912Sartem } 1304*2912Sartem dbus_message_iter_get_basic (&reply_iter, &value); 1305*2912Sartem 1306*2912Sartem dbus_message_unref (message); 1307*2912Sartem dbus_message_unref (reply); 1308*2912Sartem return (double) value; 1309*2912Sartem } 1310*2912Sartem 1311*2912Sartem /** 1312*2912Sartem * libhal_device_get_property_bool: 1313*2912Sartem * @ctx: the context for the connection to hald 1314*2912Sartem * @udi: the Unique Device Id 1315*2912Sartem * @key: name of the property 1316*2912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL 1317*2912Sartem * 1318*2912Sartem * Get the value of a property of type bool. 1319*2912Sartem * 1320*2912Sartem * Returns: Property value (boolean) 1321*2912Sartem */ 1322*2912Sartem dbus_bool_t 1323*2912Sartem libhal_device_get_property_bool (LibHalContext *ctx, 1324*2912Sartem const char *udi, const char *key, DBusError *error) 1325*2912Sartem { 1326*2912Sartem DBusMessage *message; 1327*2912Sartem DBusMessage *reply; 1328*2912Sartem DBusMessageIter iter, reply_iter; 1329*2912Sartem dbus_bool_t value; 1330*2912Sartem DBusError _error; 1331*2912Sartem 1332*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); 1333*2912Sartem 1334*2912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, 1335*2912Sartem "org.freedesktop.Hal.Device", 1336*2912Sartem "GetPropertyBoolean"); 1337*2912Sartem if (message == NULL) { 1338*2912Sartem fprintf (stderr, 1339*2912Sartem "%s %d : Couldn't allocate D-BUS message\n", 1340*2912Sartem __FILE__, __LINE__); 1341*2912Sartem return FALSE; 1342*2912Sartem } 1343*2912Sartem 1344*2912Sartem dbus_message_iter_init_append (message, &iter); 1345*2912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key); 1346*2912Sartem 1347*2912Sartem dbus_error_init (&_error); 1348*2912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection, 1349*2912Sartem message, -1, 1350*2912Sartem &_error); 1351*2912Sartem 1352*2912Sartem dbus_move_error (&_error, error); 1353*2912Sartem if (error != NULL && dbus_error_is_set (error)) { 1354*2912Sartem dbus_message_unref (message); 1355*2912Sartem return FALSE; 1356*2912Sartem } 1357*2912Sartem if (reply == NULL) { 1358*2912Sartem dbus_message_unref (message); 1359*2912Sartem return FALSE; 1360*2912Sartem } 1361*2912Sartem 1362*2912Sartem dbus_message_iter_init (reply, &reply_iter); 1363*2912Sartem 1364*2912Sartem /* now analyze reply */ 1365*2912Sartem if (dbus_message_iter_get_arg_type (&reply_iter) != 1366*2912Sartem DBUS_TYPE_BOOLEAN) { 1367*2912Sartem fprintf (stderr, 1368*2912Sartem "%s %d : property '%s' for device '%s' is not " 1369*2912Sartem "of type bool\n", __FILE__, __LINE__, key, udi); 1370*2912Sartem dbus_message_unref (message); 1371*2912Sartem dbus_message_unref (reply); 1372*2912Sartem return FALSE; 1373*2912Sartem } 1374*2912Sartem dbus_message_iter_get_basic (&reply_iter, &value); 1375*2912Sartem 1376*2912Sartem dbus_message_unref (message); 1377*2912Sartem dbus_message_unref (reply); 1378*2912Sartem return value; 1379*2912Sartem } 1380*2912Sartem 1381*2912Sartem 1382*2912Sartem /* generic helper */ 1383*2912Sartem static dbus_bool_t 1384*2912Sartem libhal_device_set_property_helper (LibHalContext *ctx, 1385*2912Sartem const char *udi, 1386*2912Sartem const char *key, 1387*2912Sartem int type, 1388*2912Sartem const char *str_value, 1389*2912Sartem dbus_int32_t int_value, 1390*2912Sartem dbus_uint64_t uint64_value, 1391*2912Sartem double double_value, 1392*2912Sartem dbus_bool_t bool_value, 1393*2912Sartem DBusError *error) 1394*2912Sartem { 1395*2912Sartem DBusMessage *message; 1396*2912Sartem DBusMessage *reply; 1397*2912Sartem DBusMessageIter iter; 1398*2912Sartem char *method_name = NULL; 1399*2912Sartem 1400*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); 1401*2912Sartem 1402*2912Sartem /** @todo sanity check incoming params */ 1403*2912Sartem switch (type) { 1404*2912Sartem case DBUS_TYPE_INVALID: 1405*2912Sartem method_name = "RemoveProperty"; 1406*2912Sartem break; 1407*2912Sartem case DBUS_TYPE_STRING: 1408*2912Sartem method_name = "SetPropertyString"; 1409*2912Sartem break; 1410*2912Sartem case DBUS_TYPE_INT32: 1411*2912Sartem case DBUS_TYPE_UINT64: 1412*2912Sartem method_name = "SetPropertyInteger"; 1413*2912Sartem break; 1414*2912Sartem case DBUS_TYPE_DOUBLE: 1415*2912Sartem method_name = "SetPropertyDouble"; 1416*2912Sartem break; 1417*2912Sartem case DBUS_TYPE_BOOLEAN: 1418*2912Sartem method_name = "SetPropertyBoolean"; 1419*2912Sartem break; 1420*2912Sartem 1421*2912Sartem default: 1422*2912Sartem /* cannot happen; is not callable from outside this file */ 1423*2912Sartem break; 1424*2912Sartem } 1425*2912Sartem 1426*2912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, 1427*2912Sartem "org.freedesktop.Hal.Device", 1428*2912Sartem method_name); 1429*2912Sartem if (message == NULL) { 1430*2912Sartem fprintf (stderr, 1431*2912Sartem "%s %d : Couldn't allocate D-BUS message\n", 1432*2912Sartem __FILE__, __LINE__); 1433*2912Sartem return FALSE; 1434*2912Sartem } 1435*2912Sartem 1436*2912Sartem dbus_message_iter_init_append (message, &iter); 1437*2912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key); 1438*2912Sartem switch (type) { 1439*2912Sartem case DBUS_TYPE_STRING: 1440*2912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &str_value); 1441*2912Sartem break; 1442*2912Sartem case DBUS_TYPE_INT32: 1443*2912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_INT32, &int_value); 1444*2912Sartem break; 1445*2912Sartem case DBUS_TYPE_UINT64: 1446*2912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT64, &uint64_value); 1447*2912Sartem break; 1448*2912Sartem case DBUS_TYPE_DOUBLE: 1449*2912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_DOUBLE, &double_value); 1450*2912Sartem break; 1451*2912Sartem case DBUS_TYPE_BOOLEAN: 1452*2912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN, &bool_value); 1453*2912Sartem break; 1454*2912Sartem } 1455*2912Sartem 1456*2912Sartem 1457*2912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection, 1458*2912Sartem message, -1, 1459*2912Sartem error); 1460*2912Sartem if (dbus_error_is_set (error)) { 1461*2912Sartem dbus_message_unref (message); 1462*2912Sartem return FALSE; 1463*2912Sartem } 1464*2912Sartem 1465*2912Sartem if (reply == NULL) { 1466*2912Sartem dbus_message_unref (message); 1467*2912Sartem return FALSE; 1468*2912Sartem } 1469*2912Sartem 1470*2912Sartem dbus_message_unref (message); 1471*2912Sartem dbus_message_unref (reply); 1472*2912Sartem 1473*2912Sartem return TRUE; 1474*2912Sartem } 1475*2912Sartem 1476*2912Sartem /** 1477*2912Sartem * libhal_device_set_property_string: 1478*2912Sartem * @ctx: the context for the connection to hald 1479*2912Sartem * @udi: the Unique Device Id 1480*2912Sartem * @key: name of the property 1481*2912Sartem * @value: value of the property; a UTF8 string 1482*2912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL 1483*2912Sartem * 1484*2912Sartem * Set a property of type string. 1485*2912Sartem * 1486*2912Sartem * Returns: TRUE if the property was set, FALSE if the device didn't 1487*2912Sartem * exist or the property had a different type. 1488*2912Sartem */ 1489*2912Sartem dbus_bool_t 1490*2912Sartem libhal_device_set_property_string (LibHalContext *ctx, 1491*2912Sartem const char *udi, 1492*2912Sartem const char *key, 1493*2912Sartem const char *value, 1494*2912Sartem DBusError *error) 1495*2912Sartem { 1496*2912Sartem return libhal_device_set_property_helper (ctx, udi, key, 1497*2912Sartem DBUS_TYPE_STRING, 1498*2912Sartem value, 0, 0, 0.0f, FALSE, error); 1499*2912Sartem } 1500*2912Sartem 1501*2912Sartem /** 1502*2912Sartem * libhal_device_set_property_int: 1503*2912Sartem * @ctx: the context for the connection to hald 1504*2912Sartem * @udi: the Unique Device Id 1505*2912Sartem * @key: name of the property 1506*2912Sartem * @value: value of the property 1507*2912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL 1508*2912Sartem * 1509*2912Sartem * Set a property of type signed integer. 1510*2912Sartem * 1511*2912Sartem * Returns: TRUE if the property was set, FALSE if the device didn't 1512*2912Sartem * exist or the property had a different type. 1513*2912Sartem */ 1514*2912Sartem dbus_bool_t 1515*2912Sartem libhal_device_set_property_int (LibHalContext *ctx, const char *udi, 1516*2912Sartem const char *key, dbus_int32_t value, DBusError *error) 1517*2912Sartem { 1518*2912Sartem return libhal_device_set_property_helper (ctx, udi, key, 1519*2912Sartem DBUS_TYPE_INT32, 1520*2912Sartem NULL, value, 0, 0.0f, FALSE, error); 1521*2912Sartem } 1522*2912Sartem 1523*2912Sartem /** 1524*2912Sartem * libhal_device_set_property_uint64: 1525*2912Sartem * @ctx: the context for the connection to hald 1526*2912Sartem * @udi: the Unique Device Id 1527*2912Sartem * @key: name of the property 1528*2912Sartem * @value: value of the property 1529*2912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL 1530*2912Sartem * 1531*2912Sartem * Set a property of type unsigned integer. 1532*2912Sartem * 1533*2912Sartem * Returns: TRUE if the property was set, FALSE if the device didn't 1534*2912Sartem * exist or the property had a different type. 1535*2912Sartem */ 1536*2912Sartem dbus_bool_t 1537*2912Sartem libhal_device_set_property_uint64 (LibHalContext *ctx, const char *udi, 1538*2912Sartem const char *key, dbus_uint64_t value, DBusError *error) 1539*2912Sartem { 1540*2912Sartem return libhal_device_set_property_helper (ctx, udi, key, 1541*2912Sartem DBUS_TYPE_UINT64, 1542*2912Sartem NULL, 0, value, 0.0f, FALSE, error); 1543*2912Sartem } 1544*2912Sartem 1545*2912Sartem /** 1546*2912Sartem * libhal_device_set_property_double: 1547*2912Sartem * @ctx: the context for the connection to hald 1548*2912Sartem * @udi: the Unique Device Id 1549*2912Sartem * @key: name of the property 1550*2912Sartem * @value: value of the property 1551*2912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL 1552*2912Sartem * 1553*2912Sartem * Set a property of type double. 1554*2912Sartem * 1555*2912Sartem * Returns: TRUE if the property was set, FALSE if the device didn't 1556*2912Sartem * exist or the property had a different type. 1557*2912Sartem */ 1558*2912Sartem dbus_bool_t 1559*2912Sartem libhal_device_set_property_double (LibHalContext *ctx, const char *udi, 1560*2912Sartem const char *key, double value, DBusError *error) 1561*2912Sartem { 1562*2912Sartem return libhal_device_set_property_helper (ctx, udi, key, 1563*2912Sartem DBUS_TYPE_DOUBLE, 1564*2912Sartem NULL, 0, 0, value, FALSE, error); 1565*2912Sartem } 1566*2912Sartem 1567*2912Sartem /** 1568*2912Sartem * libhal_device_set_property_bool: 1569*2912Sartem * @ctx: the context for the connection to hald 1570*2912Sartem * @udi: the Unique Device Id 1571*2912Sartem * @key: name of the property 1572*2912Sartem * @value: value of the property 1573*2912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL 1574*2912Sartem * 1575*2912Sartem * Set a property of type bool. 1576*2912Sartem * 1577*2912Sartem * Returns: TRUE if the property was set, FALSE if the device didn't 1578*2912Sartem * exist or the property had a different type. 1579*2912Sartem */ 1580*2912Sartem dbus_bool_t 1581*2912Sartem libhal_device_set_property_bool (LibHalContext *ctx, const char *udi, 1582*2912Sartem const char *key, dbus_bool_t value, DBusError *error) 1583*2912Sartem { 1584*2912Sartem return libhal_device_set_property_helper (ctx, udi, key, 1585*2912Sartem DBUS_TYPE_BOOLEAN, 1586*2912Sartem NULL, 0, 0, 0.0f, value, error); 1587*2912Sartem } 1588*2912Sartem 1589*2912Sartem 1590*2912Sartem /** 1591*2912Sartem * libhal_device_remove_property: 1592*2912Sartem * @ctx: the context for the connection to hald 1593*2912Sartem * @udi: the Unique Device Id 1594*2912Sartem * @key: name of the property 1595*2912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL 1596*2912Sartem * 1597*2912Sartem * Remove a property. 1598*2912Sartem * 1599*2912Sartem * Returns: TRUE if the property was set, FALSE if the device didn't 1600*2912Sartem * exist 1601*2912Sartem */ 1602*2912Sartem dbus_bool_t 1603*2912Sartem libhal_device_remove_property (LibHalContext *ctx, 1604*2912Sartem const char *udi, const char *key, DBusError *error) 1605*2912Sartem { 1606*2912Sartem return libhal_device_set_property_helper (ctx, udi, key, DBUS_TYPE_INVALID, 1607*2912Sartem /* DBUS_TYPE_INVALID means remove */ 1608*2912Sartem NULL, 0, 0, 0.0f, FALSE, error); 1609*2912Sartem } 1610*2912Sartem 1611*2912Sartem /** 1612*2912Sartem * libhal_device_property_strlist_append: 1613*2912Sartem * @ctx: the context for the connection to hald 1614*2912Sartem * @udi: the Unique Device Id 1615*2912Sartem * @key: name of the property 1616*2912Sartem * @value: value to append to property 1617*2912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL 1618*2912Sartem * 1619*2912Sartem * Append to a property of type strlist. 1620*2912Sartem * 1621*2912Sartem * Returns: TRUE if the value was appended, FALSE if the device didn't 1622*2912Sartem * exist or the property had a different type. 1623*2912Sartem */ 1624*2912Sartem dbus_bool_t 1625*2912Sartem libhal_device_property_strlist_append (LibHalContext *ctx, 1626*2912Sartem const char *udi, 1627*2912Sartem const char *key, 1628*2912Sartem const char *value, 1629*2912Sartem DBusError *error) 1630*2912Sartem { 1631*2912Sartem DBusMessage *message; 1632*2912Sartem DBusMessage *reply; 1633*2912Sartem DBusMessageIter iter; 1634*2912Sartem 1635*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); 1636*2912Sartem 1637*2912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, 1638*2912Sartem "org.freedesktop.Hal.Device", 1639*2912Sartem "StringListAppend"); 1640*2912Sartem if (message == NULL) { 1641*2912Sartem fprintf (stderr, 1642*2912Sartem "%s %d : Couldn't allocate D-BUS message\n", 1643*2912Sartem __FILE__, __LINE__); 1644*2912Sartem return FALSE; 1645*2912Sartem } 1646*2912Sartem dbus_message_iter_init_append (message, &iter); 1647*2912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key); 1648*2912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &value); 1649*2912Sartem 1650*2912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection, 1651*2912Sartem message, -1, 1652*2912Sartem error); 1653*2912Sartem if (dbus_error_is_set (error)) { 1654*2912Sartem dbus_message_unref (message); 1655*2912Sartem return FALSE; 1656*2912Sartem } 1657*2912Sartem if (reply == NULL) { 1658*2912Sartem dbus_message_unref (message); 1659*2912Sartem return FALSE; 1660*2912Sartem } 1661*2912Sartem return TRUE; 1662*2912Sartem } 1663*2912Sartem 1664*2912Sartem /** 1665*2912Sartem * libhal_device_property_strlist_prepend: 1666*2912Sartem * @ctx: the context for the connection to hald 1667*2912Sartem * @udi: the Unique Device Id 1668*2912Sartem * @key: name of the property 1669*2912Sartem * @value: value to prepend to property 1670*2912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL 1671*2912Sartem * 1672*2912Sartem * Prepend to a property of type strlist. 1673*2912Sartem * 1674*2912Sartem * Returns: TRUE if the value was prepended, FALSE if the device 1675*2912Sartem * didn't exist or the property had a different type. 1676*2912Sartem */ 1677*2912Sartem dbus_bool_t 1678*2912Sartem libhal_device_property_strlist_prepend (LibHalContext *ctx, 1679*2912Sartem const char *udi, 1680*2912Sartem const char *key, 1681*2912Sartem const char *value, 1682*2912Sartem DBusError *error) 1683*2912Sartem { 1684*2912Sartem DBusMessage *message; 1685*2912Sartem DBusMessage *reply; 1686*2912Sartem DBusMessageIter iter; 1687*2912Sartem 1688*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); 1689*2912Sartem 1690*2912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, 1691*2912Sartem "org.freedesktop.Hal.Device", 1692*2912Sartem "StringListPrepend"); 1693*2912Sartem if (message == NULL) { 1694*2912Sartem fprintf (stderr, 1695*2912Sartem "%s %d : Couldn't allocate D-BUS message\n", 1696*2912Sartem __FILE__, __LINE__); 1697*2912Sartem return FALSE; 1698*2912Sartem } 1699*2912Sartem dbus_message_iter_init_append (message, &iter); 1700*2912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key); 1701*2912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &value); 1702*2912Sartem 1703*2912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection, 1704*2912Sartem message, -1, 1705*2912Sartem error); 1706*2912Sartem if (dbus_error_is_set (error)) { 1707*2912Sartem dbus_message_unref (message); 1708*2912Sartem return FALSE; 1709*2912Sartem } 1710*2912Sartem if (reply == NULL) { 1711*2912Sartem dbus_message_unref (message); 1712*2912Sartem return FALSE; 1713*2912Sartem } 1714*2912Sartem return TRUE; 1715*2912Sartem } 1716*2912Sartem 1717*2912Sartem /** 1718*2912Sartem * libhal_device_property_strlist_remove_index: 1719*2912Sartem * @ctx: the context for the connection to hald 1720*2912Sartem * @udi: the Unique Device Id 1721*2912Sartem * @key: name of the property 1722*2912Sartem * @idx: index of string to remove in the strlist 1723*2912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL 1724*2912Sartem * 1725*2912Sartem * Remove a specified string from a property of type strlist. 1726*2912Sartem * 1727*2912Sartem * Returns: TRUE if the string was removed, FALSE if the device didn't 1728*2912Sartem * exist or the property had a different type. 1729*2912Sartem */ 1730*2912Sartem dbus_bool_t 1731*2912Sartem libhal_device_property_strlist_remove_index (LibHalContext *ctx, 1732*2912Sartem const char *udi, 1733*2912Sartem const char *key, 1734*2912Sartem unsigned int idx, 1735*2912Sartem DBusError *error) 1736*2912Sartem { 1737*2912Sartem DBusMessage *message; 1738*2912Sartem DBusMessage *reply; 1739*2912Sartem DBusMessageIter iter; 1740*2912Sartem 1741*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); 1742*2912Sartem 1743*2912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, 1744*2912Sartem "org.freedesktop.Hal.Device", 1745*2912Sartem "StringListRemoveIndex"); 1746*2912Sartem if (message == NULL) { 1747*2912Sartem fprintf (stderr, 1748*2912Sartem "%s %d : Couldn't allocate D-BUS message\n", 1749*2912Sartem __FILE__, __LINE__); 1750*2912Sartem return FALSE; 1751*2912Sartem } 1752*2912Sartem dbus_message_iter_init_append (message, &iter); 1753*2912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key); 1754*2912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT32, &idx); 1755*2912Sartem 1756*2912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection, 1757*2912Sartem message, -1, 1758*2912Sartem error); 1759*2912Sartem if (dbus_error_is_set (error)) { 1760*2912Sartem dbus_message_unref (message); 1761*2912Sartem return FALSE; 1762*2912Sartem } 1763*2912Sartem if (reply == NULL) { 1764*2912Sartem dbus_message_unref (message); 1765*2912Sartem return FALSE; 1766*2912Sartem } 1767*2912Sartem return TRUE; 1768*2912Sartem } 1769*2912Sartem 1770*2912Sartem /** 1771*2912Sartem * libhal_device_property_strlist_remove: 1772*2912Sartem * @ctx: the context for the connection to hald 1773*2912Sartem * @udi: the Unique Device Id 1774*2912Sartem * @key: name of the property 1775*2912Sartem * @value: the string to remove 1776*2912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL 1777*2912Sartem * 1778*2912Sartem * Remove a specified string from a property of type strlist. 1779*2912Sartem * 1780*2912Sartem * Returns: TRUE if the string was removed, FALSE if the device didn't 1781*2912Sartem * exist or the property had a different type. 1782*2912Sartem */ 1783*2912Sartem dbus_bool_t 1784*2912Sartem libhal_device_property_strlist_remove (LibHalContext *ctx, 1785*2912Sartem const char *udi, 1786*2912Sartem const char *key, 1787*2912Sartem const char *value, DBusError *error) 1788*2912Sartem { 1789*2912Sartem DBusMessage *message; 1790*2912Sartem DBusMessage *reply; 1791*2912Sartem DBusMessageIter iter; 1792*2912Sartem 1793*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); 1794*2912Sartem 1795*2912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, 1796*2912Sartem "org.freedesktop.Hal.Device", 1797*2912Sartem "StringListRemove"); 1798*2912Sartem if (message == NULL) { 1799*2912Sartem fprintf (stderr, 1800*2912Sartem "%s %d : Couldn't allocate D-BUS message\n", 1801*2912Sartem __FILE__, __LINE__); 1802*2912Sartem return FALSE; 1803*2912Sartem } 1804*2912Sartem dbus_message_iter_init_append (message, &iter); 1805*2912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key); 1806*2912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &value); 1807*2912Sartem 1808*2912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection, 1809*2912Sartem message, -1, 1810*2912Sartem error); 1811*2912Sartem if (dbus_error_is_set (error)) { 1812*2912Sartem dbus_message_unref (message); 1813*2912Sartem return FALSE; 1814*2912Sartem } 1815*2912Sartem if (reply == NULL) { 1816*2912Sartem dbus_message_unref (message); 1817*2912Sartem return FALSE; 1818*2912Sartem } 1819*2912Sartem return TRUE; 1820*2912Sartem } 1821*2912Sartem 1822*2912Sartem 1823*2912Sartem /** 1824*2912Sartem * libhal_device_lock: 1825*2912Sartem * @ctx: the context for the connection to hald 1826*2912Sartem * @udi: the Unique Device Id 1827*2912Sartem * @reason_to_lock: a user-presentable reason why the device is locked. 1828*2912Sartem * @reason_why_locked: a pointer to store the reason why the device cannot be locked on failure, or NULL 1829*2912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL 1830*2912Sartem * 1831*2912Sartem * Take an advisory lock on the device. 1832*2912Sartem * 1833*2912Sartem * Returns: TRUE if the lock was obtained, FALSE otherwise 1834*2912Sartem */ 1835*2912Sartem dbus_bool_t 1836*2912Sartem libhal_device_lock (LibHalContext *ctx, 1837*2912Sartem const char *udi, 1838*2912Sartem const char *reason_to_lock, 1839*2912Sartem char **reason_why_locked, DBusError *error) 1840*2912Sartem { 1841*2912Sartem DBusMessage *message; 1842*2912Sartem DBusMessageIter iter; 1843*2912Sartem DBusMessage *reply; 1844*2912Sartem 1845*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); 1846*2912Sartem 1847*2912Sartem if (reason_why_locked != NULL) 1848*2912Sartem *reason_why_locked = NULL; 1849*2912Sartem 1850*2912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", 1851*2912Sartem udi, 1852*2912Sartem "org.freedesktop.Hal.Device", 1853*2912Sartem "Lock"); 1854*2912Sartem 1855*2912Sartem if (message == NULL) { 1856*2912Sartem fprintf (stderr, 1857*2912Sartem "%s %d : Couldn't allocate D-BUS message\n", 1858*2912Sartem __FILE__, __LINE__); 1859*2912Sartem return FALSE; 1860*2912Sartem } 1861*2912Sartem 1862*2912Sartem dbus_message_iter_init_append (message, &iter); 1863*2912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &reason_to_lock); 1864*2912Sartem 1865*2912Sartem 1866*2912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection, 1867*2912Sartem message, -1, 1868*2912Sartem error); 1869*2912Sartem 1870*2912Sartem if (dbus_error_is_set (error)) { 1871*2912Sartem if (strcmp (error->name, 1872*2912Sartem "org.freedesktop.Hal.DeviceAlreadyLocked") == 0) { 1873*2912Sartem if (reason_why_locked != NULL) { 1874*2912Sartem *reason_why_locked = 1875*2912Sartem dbus_malloc0 (strlen (error->message) + 1); 1876*2912Sartem strcpy (*reason_why_locked, error->message); 1877*2912Sartem } 1878*2912Sartem } 1879*2912Sartem 1880*2912Sartem dbus_message_unref (message); 1881*2912Sartem return FALSE; 1882*2912Sartem } 1883*2912Sartem 1884*2912Sartem dbus_message_unref (message); 1885*2912Sartem 1886*2912Sartem if (reply == NULL) 1887*2912Sartem return FALSE; 1888*2912Sartem 1889*2912Sartem dbus_message_unref (reply); 1890*2912Sartem 1891*2912Sartem return TRUE; 1892*2912Sartem } 1893*2912Sartem 1894*2912Sartem /** 1895*2912Sartem * libhal_device_unlock: 1896*2912Sartem * @ctx: the context for the connection to hald 1897*2912Sartem * @udi: the Unique Device Id 1898*2912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL 1899*2912Sartem * 1900*2912Sartem * Release an advisory lock on the device. 1901*2912Sartem * 1902*2912Sartem * Returns: TRUE if the device was successfully unlocked, 1903*2912Sartem * FALSE otherwise 1904*2912Sartem */ 1905*2912Sartem dbus_bool_t 1906*2912Sartem libhal_device_unlock (LibHalContext *ctx, 1907*2912Sartem const char *udi, DBusError *error) 1908*2912Sartem { 1909*2912Sartem DBusMessage *message; 1910*2912Sartem DBusMessage *reply; 1911*2912Sartem 1912*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); 1913*2912Sartem 1914*2912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", 1915*2912Sartem udi, 1916*2912Sartem "org.freedesktop.Hal.Device", 1917*2912Sartem "Unlock"); 1918*2912Sartem 1919*2912Sartem if (message == NULL) { 1920*2912Sartem fprintf (stderr, 1921*2912Sartem "%s %d : Couldn't allocate D-BUS message\n", 1922*2912Sartem __FILE__, __LINE__); 1923*2912Sartem return FALSE; 1924*2912Sartem } 1925*2912Sartem 1926*2912Sartem 1927*2912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection, 1928*2912Sartem message, -1, 1929*2912Sartem error); 1930*2912Sartem 1931*2912Sartem if (dbus_error_is_set (error)) { 1932*2912Sartem dbus_message_unref (message); 1933*2912Sartem return FALSE; 1934*2912Sartem } 1935*2912Sartem 1936*2912Sartem dbus_message_unref (message); 1937*2912Sartem 1938*2912Sartem if (reply == NULL) 1939*2912Sartem return FALSE; 1940*2912Sartem 1941*2912Sartem dbus_message_unref (reply); 1942*2912Sartem 1943*2912Sartem return TRUE; 1944*2912Sartem } 1945*2912Sartem 1946*2912Sartem 1947*2912Sartem /** 1948*2912Sartem * libhal_new_device: 1949*2912Sartem * @ctx: the context for the connection to hald 1950*2912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL 1951*2912Sartem * 1952*2912Sartem * Create a new device object which will be hidden from applications 1953*2912Sartem * until the CommitToGdl(), ie. libhal_device_commit_to_gdl(), method 1954*2912Sartem * is called. Note that the program invoking this method needs to run 1955*2912Sartem * with super user privileges. 1956*2912Sartem * 1957*2912Sartem * Returns: Temporary device unique id or NULL if there was a 1958*2912Sartem * problem. This string must be freed by the caller. 1959*2912Sartem */ 1960*2912Sartem char * 1961*2912Sartem libhal_new_device (LibHalContext *ctx, DBusError *error) 1962*2912Sartem { 1963*2912Sartem DBusMessage *message; 1964*2912Sartem DBusMessage *reply; 1965*2912Sartem DBusMessageIter reply_iter; 1966*2912Sartem char *value; 1967*2912Sartem char *dbus_str; 1968*2912Sartem 1969*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL); 1970*2912Sartem 1971*2912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", 1972*2912Sartem "/org/freedesktop/Hal/Manager", 1973*2912Sartem "org.freedesktop.Hal.Manager", 1974*2912Sartem "NewDevice"); 1975*2912Sartem if (message == NULL) { 1976*2912Sartem fprintf (stderr, 1977*2912Sartem "%s %d : Couldn't allocate D-BUS message\n", 1978*2912Sartem __FILE__, __LINE__); 1979*2912Sartem return NULL; 1980*2912Sartem } 1981*2912Sartem 1982*2912Sartem 1983*2912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection, 1984*2912Sartem message, -1, 1985*2912Sartem error); 1986*2912Sartem if (dbus_error_is_set (error)) { 1987*2912Sartem dbus_message_unref (message); 1988*2912Sartem return NULL; 1989*2912Sartem } 1990*2912Sartem if (reply == NULL) { 1991*2912Sartem dbus_message_unref (message); 1992*2912Sartem return NULL; 1993*2912Sartem } 1994*2912Sartem 1995*2912Sartem dbus_message_iter_init (reply, &reply_iter); 1996*2912Sartem 1997*2912Sartem /* now analyze reply */ 1998*2912Sartem if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_STRING) { 1999*2912Sartem fprintf (stderr, 2000*2912Sartem "%s %d : expected a string in reply to NewDevice\n", 2001*2912Sartem __FILE__, __LINE__); 2002*2912Sartem dbus_message_unref (message); 2003*2912Sartem dbus_message_unref (reply); 2004*2912Sartem return NULL; 2005*2912Sartem } 2006*2912Sartem 2007*2912Sartem dbus_message_iter_get_basic (&reply_iter, &dbus_str); 2008*2912Sartem value = (char *) ((dbus_str != NULL) ? strdup (dbus_str) : NULL); 2009*2912Sartem if (value == NULL) { 2010*2912Sartem fprintf (stderr, "%s %d : error allocating memory\n", 2011*2912Sartem __FILE__, __LINE__); 2012*2912Sartem } 2013*2912Sartem 2014*2912Sartem dbus_message_unref (message); 2015*2912Sartem dbus_message_unref (reply); 2016*2912Sartem return value; 2017*2912Sartem } 2018*2912Sartem 2019*2912Sartem 2020*2912Sartem /** 2021*2912Sartem * libhal_device_commit_to_gdl: 2022*2912Sartem * @ctx: the context for the connection to hald 2023*2912Sartem * @temp_udi: the temporary unique device id as returned by libhal_new_device() 2024*2912Sartem * @udi: the new unique device id. 2025*2912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL 2026*2912Sartem * 2027*2912Sartem * When a hidden device has been built using the NewDevice method, 2028*2912Sartem * ie. libhal_new_device(), and the org.freedesktop.Hal.Device 2029*2912Sartem * interface this function will commit it to the global device list. 2030*2912Sartem * 2031*2912Sartem * This means that the device object will be visible to applications 2032*2912Sartem * and the HAL daemon will possibly attempt to boot the device 2033*2912Sartem * (depending on the property RequireEnable). 2034*2912Sartem * 2035*2912Sartem * Note that the program invoking this method needs to run with super 2036*2912Sartem * user privileges. 2037*2912Sartem * 2038*2912Sartem * Returns: FALSE if the given unique device id is already in use. 2039*2912Sartem */ 2040*2912Sartem dbus_bool_t 2041*2912Sartem libhal_device_commit_to_gdl (LibHalContext *ctx, 2042*2912Sartem const char *temp_udi, const char *udi, DBusError *error) 2043*2912Sartem { 2044*2912Sartem DBusMessage *message; 2045*2912Sartem DBusMessage *reply; 2046*2912Sartem DBusMessageIter iter; 2047*2912Sartem 2048*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); 2049*2912Sartem 2050*2912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", 2051*2912Sartem "/org/freedesktop/Hal/Manager", 2052*2912Sartem "org.freedesktop.Hal.Manager", 2053*2912Sartem "CommitToGdl"); 2054*2912Sartem if (message == NULL) { 2055*2912Sartem fprintf (stderr, 2056*2912Sartem "%s %d : Couldn't allocate D-BUS message\n", 2057*2912Sartem __FILE__, __LINE__); 2058*2912Sartem return FALSE; 2059*2912Sartem } 2060*2912Sartem 2061*2912Sartem dbus_message_iter_init_append (message, &iter); 2062*2912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &temp_udi); 2063*2912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &udi); 2064*2912Sartem 2065*2912Sartem 2066*2912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection, 2067*2912Sartem message, -1, 2068*2912Sartem error); 2069*2912Sartem if (dbus_error_is_set (error)) { 2070*2912Sartem dbus_message_unref (message); 2071*2912Sartem return FALSE; 2072*2912Sartem } 2073*2912Sartem if (reply == NULL) { 2074*2912Sartem dbus_message_unref (message); 2075*2912Sartem return FALSE; 2076*2912Sartem } 2077*2912Sartem 2078*2912Sartem dbus_message_unref (message); 2079*2912Sartem dbus_message_unref (reply); 2080*2912Sartem return TRUE; 2081*2912Sartem } 2082*2912Sartem 2083*2912Sartem /** 2084*2912Sartem * libhal_remove_device: 2085*2912Sartem * @ctx: the context for the connection to hald 2086*2912Sartem * @udi: the Unique device id. 2087*2912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL 2088*2912Sartem * 2089*2912Sartem * This method can be invoked when a device is removed. The HAL daemon 2090*2912Sartem * will shut down the device. Note that the device may still be in the 2091*2912Sartem * device list if the Persistent property is set to true. 2092*2912Sartem * 2093*2912Sartem * Note that the program invoking this method needs to run with super 2094*2912Sartem * user privileges. 2095*2912Sartem * 2096*2912Sartem * Returns: TRUE if the device was removed, FALSE otherwise 2097*2912Sartem */ 2098*2912Sartem dbus_bool_t 2099*2912Sartem libhal_remove_device (LibHalContext *ctx, const char *udi, DBusError *error) 2100*2912Sartem { 2101*2912Sartem DBusMessage *message; 2102*2912Sartem DBusMessage *reply; 2103*2912Sartem DBusMessageIter iter; 2104*2912Sartem 2105*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); 2106*2912Sartem 2107*2912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", 2108*2912Sartem "/org/freedesktop/Hal/Manager", 2109*2912Sartem "org.freedesktop.Hal.Manager", 2110*2912Sartem "Remove"); 2111*2912Sartem if (message == NULL) { 2112*2912Sartem fprintf (stderr, 2113*2912Sartem "%s %d : Couldn't allocate D-BUS message\n", 2114*2912Sartem __FILE__, __LINE__); 2115*2912Sartem return FALSE; 2116*2912Sartem } 2117*2912Sartem 2118*2912Sartem dbus_message_iter_init_append (message, &iter); 2119*2912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &udi); 2120*2912Sartem 2121*2912Sartem 2122*2912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection, 2123*2912Sartem message, -1, 2124*2912Sartem error); 2125*2912Sartem if (dbus_error_is_set (error)) { 2126*2912Sartem dbus_message_unref (message); 2127*2912Sartem return FALSE; 2128*2912Sartem } 2129*2912Sartem if (reply == NULL) { 2130*2912Sartem dbus_message_unref (message); 2131*2912Sartem return FALSE; 2132*2912Sartem } 2133*2912Sartem 2134*2912Sartem dbus_message_unref (message); 2135*2912Sartem dbus_message_unref (reply); 2136*2912Sartem return TRUE; 2137*2912Sartem } 2138*2912Sartem 2139*2912Sartem /** 2140*2912Sartem * libhal_device_exists: 2141*2912Sartem * @ctx: the context for the connection to hald 2142*2912Sartem * @udi: the Unique device id. 2143*2912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL 2144*2912Sartem * 2145*2912Sartem * Determine if a device exists. 2146*2912Sartem * 2147*2912Sartem * Returns: TRUE if the device exists 2148*2912Sartem */ 2149*2912Sartem dbus_bool_t 2150*2912Sartem libhal_device_exists (LibHalContext *ctx, const char *udi, DBusError *error) 2151*2912Sartem { 2152*2912Sartem DBusMessage *message; 2153*2912Sartem DBusMessage *reply; 2154*2912Sartem DBusMessageIter iter, reply_iter; 2155*2912Sartem dbus_bool_t value; 2156*2912Sartem DBusError _error; 2157*2912Sartem 2158*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); 2159*2912Sartem 2160*2912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", 2161*2912Sartem "/org/freedesktop/Hal/Manager", 2162*2912Sartem "org.freedesktop.Hal.Manager", 2163*2912Sartem "DeviceExists"); 2164*2912Sartem if (message == NULL) { 2165*2912Sartem fprintf (stderr, 2166*2912Sartem "%s %d : Couldn't allocate D-BUS message\n", 2167*2912Sartem __FILE__, __LINE__); 2168*2912Sartem return FALSE; 2169*2912Sartem } 2170*2912Sartem 2171*2912Sartem dbus_message_iter_init_append (message, &iter); 2172*2912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &udi); 2173*2912Sartem 2174*2912Sartem dbus_error_init (&_error); 2175*2912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection, 2176*2912Sartem message, -1, 2177*2912Sartem &_error); 2178*2912Sartem 2179*2912Sartem dbus_move_error (&_error, error); 2180*2912Sartem if (error != NULL && dbus_error_is_set (error)) { 2181*2912Sartem dbus_message_unref (message); 2182*2912Sartem return FALSE; 2183*2912Sartem } 2184*2912Sartem if (reply == NULL) { 2185*2912Sartem dbus_message_unref (message); 2186*2912Sartem return FALSE; 2187*2912Sartem } 2188*2912Sartem 2189*2912Sartem dbus_message_iter_init (reply, &reply_iter); 2190*2912Sartem 2191*2912Sartem /* now analyze reply */ 2192*2912Sartem if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_BOOLEAN) { 2193*2912Sartem fprintf (stderr, 2194*2912Sartem "%s %d : expected a bool in reply to DeviceExists\n", 2195*2912Sartem __FILE__, __LINE__); 2196*2912Sartem dbus_message_unref (message); 2197*2912Sartem dbus_message_unref (reply); 2198*2912Sartem return FALSE; 2199*2912Sartem } 2200*2912Sartem 2201*2912Sartem dbus_message_iter_get_basic (&reply_iter, &value); 2202*2912Sartem 2203*2912Sartem dbus_message_unref (message); 2204*2912Sartem dbus_message_unref (reply); 2205*2912Sartem return value; 2206*2912Sartem } 2207*2912Sartem 2208*2912Sartem /** 2209*2912Sartem * libhal_device_property_exists: 2210*2912Sartem * @ctx: the context for the connection to hald 2211*2912Sartem * @udi: the Unique device id. 2212*2912Sartem * @key: name of the property 2213*2912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL 2214*2912Sartem * 2215*2912Sartem * Determine if a property on a device exists. 2216*2912Sartem * 2217*2912Sartem * Returns: TRUE if the device exists, FALSE otherwise 2218*2912Sartem */ 2219*2912Sartem dbus_bool_t 2220*2912Sartem libhal_device_property_exists (LibHalContext *ctx, 2221*2912Sartem const char *udi, const char *key, DBusError *error) 2222*2912Sartem { 2223*2912Sartem DBusMessage *message; 2224*2912Sartem DBusMessage *reply; 2225*2912Sartem DBusMessageIter iter, reply_iter; 2226*2912Sartem dbus_bool_t value; 2227*2912Sartem DBusError _error; 2228*2912Sartem 2229*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); 2230*2912Sartem 2231*2912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, 2232*2912Sartem "org.freedesktop.Hal.Device", 2233*2912Sartem "PropertyExists"); 2234*2912Sartem if (message == NULL) { 2235*2912Sartem fprintf (stderr, 2236*2912Sartem "%s %d : Couldn't allocate D-BUS message\n", 2237*2912Sartem __FILE__, __LINE__); 2238*2912Sartem return FALSE; 2239*2912Sartem } 2240*2912Sartem 2241*2912Sartem dbus_message_iter_init_append (message, &iter); 2242*2912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key); 2243*2912Sartem 2244*2912Sartem dbus_error_init (&_error); 2245*2912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection, 2246*2912Sartem message, -1, 2247*2912Sartem &_error); 2248*2912Sartem 2249*2912Sartem dbus_move_error (&_error, error); 2250*2912Sartem if (error != NULL && dbus_error_is_set (error)) { 2251*2912Sartem dbus_message_unref (message); 2252*2912Sartem return FALSE; 2253*2912Sartem } 2254*2912Sartem if (reply == NULL) { 2255*2912Sartem dbus_message_unref (message); 2256*2912Sartem return FALSE; 2257*2912Sartem } 2258*2912Sartem 2259*2912Sartem dbus_message_iter_init (reply, &reply_iter); 2260*2912Sartem 2261*2912Sartem /* now analyse reply */ 2262*2912Sartem if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_BOOLEAN) { 2263*2912Sartem fprintf (stderr, "%s %d : expected a bool in reply to " 2264*2912Sartem "PropertyExists\n", __FILE__, __LINE__); 2265*2912Sartem dbus_message_unref (message); 2266*2912Sartem dbus_message_unref (reply); 2267*2912Sartem return FALSE; 2268*2912Sartem } 2269*2912Sartem 2270*2912Sartem dbus_message_iter_get_basic (&reply_iter, &value); 2271*2912Sartem 2272*2912Sartem dbus_message_unref (message); 2273*2912Sartem dbus_message_unref (reply); 2274*2912Sartem return value; 2275*2912Sartem } 2276*2912Sartem 2277*2912Sartem /** 2278*2912Sartem * libhal_merge_properties: 2279*2912Sartem * @ctx: the context for the connection to hald 2280*2912Sartem * @target_udi: the Unique device id of target device to merge to 2281*2912Sartem * @source_udi: the Unique device id of device to merge from 2282*2912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL 2283*2912Sartem * 2284*2912Sartem * Merge properties from one device to another. 2285*2912Sartem * 2286*2912Sartem * Returns: TRUE if the properties were merged, FALSE otherwise 2287*2912Sartem */ 2288*2912Sartem dbus_bool_t 2289*2912Sartem libhal_merge_properties (LibHalContext *ctx, 2290*2912Sartem const char *target_udi, const char *source_udi, DBusError *error) 2291*2912Sartem { 2292*2912Sartem DBusMessage *message; 2293*2912Sartem DBusMessage *reply; 2294*2912Sartem DBusMessageIter iter; 2295*2912Sartem 2296*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); 2297*2912Sartem 2298*2912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", 2299*2912Sartem "/org/freedesktop/Hal/Manager", 2300*2912Sartem "org.freedesktop.Hal.Manager", 2301*2912Sartem "MergeProperties"); 2302*2912Sartem if (message == NULL) { 2303*2912Sartem fprintf (stderr, 2304*2912Sartem "%s %d : Couldn't allocate D-BUS message\n", 2305*2912Sartem __FILE__, __LINE__); 2306*2912Sartem return FALSE; 2307*2912Sartem } 2308*2912Sartem 2309*2912Sartem dbus_message_iter_init_append (message, &iter); 2310*2912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &target_udi); 2311*2912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &source_udi); 2312*2912Sartem 2313*2912Sartem 2314*2912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection, 2315*2912Sartem message, -1, 2316*2912Sartem error); 2317*2912Sartem if (dbus_error_is_set (error)) { 2318*2912Sartem dbus_message_unref (message); 2319*2912Sartem return FALSE; 2320*2912Sartem } 2321*2912Sartem if (reply == NULL) { 2322*2912Sartem dbus_message_unref (message); 2323*2912Sartem return FALSE; 2324*2912Sartem } 2325*2912Sartem 2326*2912Sartem dbus_message_unref (message); 2327*2912Sartem dbus_message_unref (reply); 2328*2912Sartem return TRUE; 2329*2912Sartem } 2330*2912Sartem 2331*2912Sartem /** 2332*2912Sartem * libhal_device_matches: 2333*2912Sartem * @ctx: the context for the connection to hald 2334*2912Sartem * @udi1: the Unique Device Id for device 1 2335*2912Sartem * @udi2: the Unique Device Id for device 2 2336*2912Sartem * @property_namespace: the namespace for set of devices, e.g. "usb" 2337*2912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL 2338*2912Sartem * 2339*2912Sartem * Check a set of properties for two devices matches. 2340*2912Sartem * 2341*2912Sartem * Checks that all properties where keys, starting with a given value 2342*2912Sartem * (namespace), of the first device is in the second device and that 2343*2912Sartem * they got the same value and type. 2344*2912Sartem * 2345*2912Sartem * Note that the other inclusion isn't tested, so there could be 2346*2912Sartem * properties (from the given namespace) in the second device not 2347*2912Sartem * present in the first device. 2348*2912Sartem * 2349*2912Sartem * Returns: TRUE if all properties starting with the given namespace 2350*2912Sartem * parameter from one device is in the other and have the same value. 2351*2912Sartem */ 2352*2912Sartem dbus_bool_t 2353*2912Sartem libhal_device_matches (LibHalContext *ctx, 2354*2912Sartem const char *udi1, const char *udi2, 2355*2912Sartem const char *property_namespace, DBusError *error) 2356*2912Sartem { 2357*2912Sartem DBusMessage *message; 2358*2912Sartem DBusMessage *reply; 2359*2912Sartem DBusMessageIter iter, reply_iter; 2360*2912Sartem dbus_bool_t value; 2361*2912Sartem DBusError _error; 2362*2912Sartem 2363*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); 2364*2912Sartem 2365*2912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", 2366*2912Sartem "/org/freedesktop/Hal/Manager", 2367*2912Sartem "org.freedesktop.Hal.Manager", 2368*2912Sartem "DeviceMatches"); 2369*2912Sartem if (message == NULL) { 2370*2912Sartem fprintf (stderr, 2371*2912Sartem "%s %d : Couldn't allocate D-BUS message\n", 2372*2912Sartem __FILE__, __LINE__); 2373*2912Sartem return FALSE; 2374*2912Sartem } 2375*2912Sartem 2376*2912Sartem dbus_message_iter_init_append (message, &iter); 2377*2912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, udi1); 2378*2912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, udi2); 2379*2912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, property_namespace); 2380*2912Sartem 2381*2912Sartem dbus_error_init (&_error); 2382*2912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection, 2383*2912Sartem message, -1, 2384*2912Sartem &_error); 2385*2912Sartem 2386*2912Sartem dbus_move_error (&_error, error); 2387*2912Sartem if (error != NULL && dbus_error_is_set (error)) { 2388*2912Sartem dbus_message_unref (message); 2389*2912Sartem return FALSE; 2390*2912Sartem } 2391*2912Sartem if (reply == NULL) { 2392*2912Sartem dbus_message_unref (message); 2393*2912Sartem return FALSE; 2394*2912Sartem } 2395*2912Sartem /* now analyse reply */ 2396*2912Sartem dbus_message_iter_init (reply, &reply_iter); 2397*2912Sartem 2398*2912Sartem if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_BOOLEAN) { 2399*2912Sartem fprintf (stderr, 2400*2912Sartem "%s %d : expected a bool in reply to DeviceMatches\n", 2401*2912Sartem __FILE__, __LINE__); 2402*2912Sartem dbus_message_unref (message); 2403*2912Sartem dbus_message_unref (reply); 2404*2912Sartem return FALSE; 2405*2912Sartem } 2406*2912Sartem 2407*2912Sartem dbus_message_iter_get_basic (&reply_iter, &value); 2408*2912Sartem 2409*2912Sartem dbus_message_unref (message); 2410*2912Sartem dbus_message_unref (reply); 2411*2912Sartem return value; 2412*2912Sartem } 2413*2912Sartem 2414*2912Sartem /** 2415*2912Sartem * libhal_device_print: 2416*2912Sartem * @ctx: the context for the connection to hald 2417*2912Sartem * @udi: the Unique Device Id 2418*2912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL 2419*2912Sartem * 2420*2912Sartem * Print a device to stdout; useful for debugging. 2421*2912Sartem * 2422*2912Sartem * Returns: TRUE if device's information could be obtained, FALSE otherwise 2423*2912Sartem */ 2424*2912Sartem dbus_bool_t 2425*2912Sartem libhal_device_print (LibHalContext *ctx, const char *udi, DBusError *error) 2426*2912Sartem { 2427*2912Sartem int type; 2428*2912Sartem char *key; 2429*2912Sartem LibHalPropertySet *pset; 2430*2912Sartem LibHalPropertySetIterator i; 2431*2912Sartem 2432*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); 2433*2912Sartem 2434*2912Sartem printf ("device_id = %s\n", udi); 2435*2912Sartem 2436*2912Sartem if ((pset = libhal_device_get_all_properties (ctx, udi, error)) == NULL) 2437*2912Sartem return FALSE; 2438*2912Sartem 2439*2912Sartem for (libhal_psi_init (&i, pset); libhal_psi_has_more (&i); 2440*2912Sartem libhal_psi_next (&i)) { 2441*2912Sartem type = libhal_psi_get_type (&i); 2442*2912Sartem key = libhal_psi_get_key (&i); 2443*2912Sartem 2444*2912Sartem switch (type) { 2445*2912Sartem case LIBHAL_PROPERTY_TYPE_STRING: 2446*2912Sartem printf (" %s = '%s' (string)\n", key, 2447*2912Sartem libhal_psi_get_string (&i)); 2448*2912Sartem break; 2449*2912Sartem case LIBHAL_PROPERTY_TYPE_INT32: 2450*2912Sartem printf (" %s = %d = 0x%x (int)\n", key, 2451*2912Sartem libhal_psi_get_int (&i), 2452*2912Sartem libhal_psi_get_int (&i)); 2453*2912Sartem break; 2454*2912Sartem case LIBHAL_PROPERTY_TYPE_UINT64: 2455*2912Sartem printf (" %s = %llu = 0x%llx (uint64)\n", key, 2456*2912Sartem (long long unsigned int) libhal_psi_get_uint64 (&i), 2457*2912Sartem (long long unsigned int) libhal_psi_get_uint64 (&i)); 2458*2912Sartem break; 2459*2912Sartem case LIBHAL_PROPERTY_TYPE_BOOLEAN: 2460*2912Sartem printf (" %s = %s (bool)\n", key, 2461*2912Sartem (libhal_psi_get_bool (&i) ? "true" : 2462*2912Sartem "false")); 2463*2912Sartem break; 2464*2912Sartem case LIBHAL_PROPERTY_TYPE_DOUBLE: 2465*2912Sartem printf (" %s = %g (double)\n", key, 2466*2912Sartem libhal_psi_get_double (&i)); 2467*2912Sartem break; 2468*2912Sartem case LIBHAL_PROPERTY_TYPE_STRLIST: 2469*2912Sartem { 2470*2912Sartem unsigned int j; 2471*2912Sartem char **str_list; 2472*2912Sartem 2473*2912Sartem str_list = libhal_psi_get_strlist (&i); 2474*2912Sartem printf (" %s = [", key); 2475*2912Sartem for (j = 0; str_list[j] != NULL; j++) { 2476*2912Sartem printf ("'%s'", str_list[j]); 2477*2912Sartem if (str_list[j+1] != NULL) 2478*2912Sartem printf (", "); 2479*2912Sartem } 2480*2912Sartem printf ("] (string list)\n"); 2481*2912Sartem 2482*2912Sartem break; 2483*2912Sartem } 2484*2912Sartem default: 2485*2912Sartem printf (" *** unknown type for key %s\n", key); 2486*2912Sartem break; 2487*2912Sartem } 2488*2912Sartem } 2489*2912Sartem 2490*2912Sartem libhal_free_property_set (pset); 2491*2912Sartem 2492*2912Sartem return TRUE; 2493*2912Sartem } 2494*2912Sartem 2495*2912Sartem /** 2496*2912Sartem * libhal_manager_find_device_string_match: 2497*2912Sartem * @ctx: the context for the connection to hald 2498*2912Sartem * @key: name of the property 2499*2912Sartem * @value: the value to match 2500*2912Sartem * @num_devices: pointer to store number of devices 2501*2912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL 2502*2912Sartem * 2503*2912Sartem * Find a device in the GDL where a single string property matches a 2504*2912Sartem * given value. 2505*2912Sartem * 2506*2912Sartem * Returns: UDI of devices; free with libhal_free_string_array() 2507*2912Sartem */ 2508*2912Sartem char ** 2509*2912Sartem libhal_manager_find_device_string_match (LibHalContext *ctx, 2510*2912Sartem const char *key, 2511*2912Sartem const char *value, int *num_devices, DBusError *error) 2512*2912Sartem { 2513*2912Sartem DBusMessage *message; 2514*2912Sartem DBusMessage *reply; 2515*2912Sartem DBusMessageIter iter, iter_array, reply_iter; 2516*2912Sartem char **hal_device_names; 2517*2912Sartem DBusError _error; 2518*2912Sartem 2519*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL); 2520*2912Sartem 2521*2912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", 2522*2912Sartem "/org/freedesktop/Hal/Manager", 2523*2912Sartem "org.freedesktop.Hal.Manager", 2524*2912Sartem "FindDeviceStringMatch"); 2525*2912Sartem if (message == NULL) { 2526*2912Sartem fprintf (stderr, 2527*2912Sartem "%s %d : Couldn't allocate D-BUS message\n", 2528*2912Sartem __FILE__, __LINE__); 2529*2912Sartem return NULL; 2530*2912Sartem } 2531*2912Sartem 2532*2912Sartem dbus_message_iter_init_append (message, &iter); 2533*2912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key); 2534*2912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &value); 2535*2912Sartem 2536*2912Sartem dbus_error_init (&_error); 2537*2912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection, 2538*2912Sartem message, -1, 2539*2912Sartem &_error); 2540*2912Sartem 2541*2912Sartem dbus_move_error (&_error, error); 2542*2912Sartem if (error != NULL && dbus_error_is_set (error)) { 2543*2912Sartem dbus_message_unref (message); 2544*2912Sartem return NULL; 2545*2912Sartem } 2546*2912Sartem if (reply == NULL) { 2547*2912Sartem dbus_message_unref (message); 2548*2912Sartem return NULL; 2549*2912Sartem } 2550*2912Sartem /* now analyse reply */ 2551*2912Sartem dbus_message_iter_init (reply, &reply_iter); 2552*2912Sartem 2553*2912Sartem if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_ARRAY) { 2554*2912Sartem fprintf (stderr, "%s %d : wrong reply from hald. Expecting an array.\n", __FILE__, __LINE__); 2555*2912Sartem return NULL; 2556*2912Sartem } 2557*2912Sartem 2558*2912Sartem dbus_message_iter_recurse (&reply_iter, &iter_array); 2559*2912Sartem 2560*2912Sartem hal_device_names = libhal_get_string_array_from_iter (&iter_array, num_devices); 2561*2912Sartem 2562*2912Sartem dbus_message_unref (reply); 2563*2912Sartem dbus_message_unref (message); 2564*2912Sartem 2565*2912Sartem return hal_device_names; 2566*2912Sartem } 2567*2912Sartem 2568*2912Sartem 2569*2912Sartem /** 2570*2912Sartem * libhal_device_add_capability: 2571*2912Sartem * @ctx: the context for the connection to hald 2572*2912Sartem * @udi: the Unique Device Id 2573*2912Sartem * @capability: the capability name to add 2574*2912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL 2575*2912Sartem * 2576*2912Sartem * Assign a capability to a device. 2577*2912Sartem * 2578*2912Sartem * Returns: TRUE if the capability was added, FALSE if the device didn't exist 2579*2912Sartem */ 2580*2912Sartem dbus_bool_t 2581*2912Sartem libhal_device_add_capability (LibHalContext *ctx, 2582*2912Sartem const char *udi, const char *capability, DBusError *error) 2583*2912Sartem { 2584*2912Sartem DBusMessage *message; 2585*2912Sartem DBusMessage *reply; 2586*2912Sartem DBusMessageIter iter; 2587*2912Sartem 2588*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); 2589*2912Sartem 2590*2912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, 2591*2912Sartem "org.freedesktop.Hal.Device", 2592*2912Sartem "AddCapability"); 2593*2912Sartem if (message == NULL) { 2594*2912Sartem fprintf (stderr, 2595*2912Sartem "%s %d : Couldn't allocate D-BUS message\n", 2596*2912Sartem __FILE__, __LINE__); 2597*2912Sartem return FALSE; 2598*2912Sartem } 2599*2912Sartem 2600*2912Sartem dbus_message_iter_init_append (message, &iter); 2601*2912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &capability); 2602*2912Sartem 2603*2912Sartem 2604*2912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection, 2605*2912Sartem message, -1, 2606*2912Sartem error); 2607*2912Sartem if (dbus_error_is_set (error)) { 2608*2912Sartem dbus_message_unref (message); 2609*2912Sartem return FALSE; 2610*2912Sartem } 2611*2912Sartem 2612*2912Sartem if (reply == NULL) { 2613*2912Sartem dbus_message_unref (message); 2614*2912Sartem return FALSE; 2615*2912Sartem } 2616*2912Sartem 2617*2912Sartem dbus_message_unref (reply); 2618*2912Sartem dbus_message_unref (message); 2619*2912Sartem return TRUE; 2620*2912Sartem } 2621*2912Sartem 2622*2912Sartem /** 2623*2912Sartem * libhal_device_query_capability: 2624*2912Sartem * @ctx: the context for the connection to hald 2625*2912Sartem * @udi: the Unique Device Id 2626*2912Sartem * @capability: the capability name 2627*2912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL 2628*2912Sartem * 2629*2912Sartem * Check if a device has a capability. The result is undefined if the 2630*2912Sartem * device doesn't exist. 2631*2912Sartem * 2632*2912Sartem * Returns: TRUE if the device has the capability, otherwise FALSE 2633*2912Sartem */ 2634*2912Sartem dbus_bool_t 2635*2912Sartem libhal_device_query_capability (LibHalContext *ctx, const char *udi, const char *capability, DBusError *error) 2636*2912Sartem { 2637*2912Sartem char **caps; 2638*2912Sartem unsigned int i; 2639*2912Sartem dbus_bool_t ret; 2640*2912Sartem 2641*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); 2642*2912Sartem 2643*2912Sartem ret = FALSE; 2644*2912Sartem 2645*2912Sartem caps = libhal_device_get_property_strlist (ctx, udi, "info.capabilities", error); 2646*2912Sartem if (caps != NULL) { 2647*2912Sartem for (i = 0; caps[i] != NULL; i++) { 2648*2912Sartem if (strcmp (caps[i], capability) == 0) { 2649*2912Sartem ret = TRUE; 2650*2912Sartem break; 2651*2912Sartem } 2652*2912Sartem } 2653*2912Sartem libhal_free_string_array (caps); 2654*2912Sartem } 2655*2912Sartem 2656*2912Sartem return ret; 2657*2912Sartem } 2658*2912Sartem 2659*2912Sartem /** 2660*2912Sartem * libhal_find_device_by_capability: 2661*2912Sartem * @ctx: the context for the connection to hald 2662*2912Sartem * @capability: the capability name 2663*2912Sartem * @num_devices: pointer to store number of devices 2664*2912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL 2665*2912Sartem * 2666*2912Sartem * Find devices with a given capability. 2667*2912Sartem * 2668*2912Sartem * Returns: UDI of devices; free with libhal_free_string_array() 2669*2912Sartem */ 2670*2912Sartem char ** 2671*2912Sartem libhal_find_device_by_capability (LibHalContext *ctx, 2672*2912Sartem const char *capability, int *num_devices, DBusError *error) 2673*2912Sartem { 2674*2912Sartem DBusMessage *message; 2675*2912Sartem DBusMessage *reply; 2676*2912Sartem DBusMessageIter iter, iter_array, reply_iter; 2677*2912Sartem char **hal_device_names; 2678*2912Sartem DBusError _error; 2679*2912Sartem 2680*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL); 2681*2912Sartem 2682*2912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", 2683*2912Sartem "/org/freedesktop/Hal/Manager", 2684*2912Sartem "org.freedesktop.Hal.Manager", 2685*2912Sartem "FindDeviceByCapability"); 2686*2912Sartem if (message == NULL) { 2687*2912Sartem fprintf (stderr, 2688*2912Sartem "%s %d : Couldn't allocate D-BUS message\n", 2689*2912Sartem __FILE__, __LINE__); 2690*2912Sartem return NULL; 2691*2912Sartem } 2692*2912Sartem 2693*2912Sartem dbus_message_iter_init_append (message, &iter); 2694*2912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &capability); 2695*2912Sartem 2696*2912Sartem dbus_error_init (&_error); 2697*2912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection, 2698*2912Sartem message, -1, 2699*2912Sartem &_error); 2700*2912Sartem 2701*2912Sartem dbus_move_error (&_error, error); 2702*2912Sartem if (error != NULL && dbus_error_is_set (error)) { 2703*2912Sartem dbus_message_unref (message); 2704*2912Sartem return NULL; 2705*2912Sartem } 2706*2912Sartem if (reply == NULL) { 2707*2912Sartem dbus_message_unref (message); 2708*2912Sartem return NULL; 2709*2912Sartem } 2710*2912Sartem /* now analyse reply */ 2711*2912Sartem dbus_message_iter_init (reply, &reply_iter); 2712*2912Sartem 2713*2912Sartem if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_ARRAY) { 2714*2912Sartem fprintf (stderr, "%s %d : wrong reply from hald. Expecting an array.\n", __FILE__, __LINE__); 2715*2912Sartem return NULL; 2716*2912Sartem } 2717*2912Sartem 2718*2912Sartem dbus_message_iter_recurse (&reply_iter, &iter_array); 2719*2912Sartem 2720*2912Sartem hal_device_names = libhal_get_string_array_from_iter (&iter_array, num_devices); 2721*2912Sartem 2722*2912Sartem dbus_message_unref (reply); 2723*2912Sartem dbus_message_unref (message); 2724*2912Sartem 2725*2912Sartem return hal_device_names; 2726*2912Sartem } 2727*2912Sartem 2728*2912Sartem /** 2729*2912Sartem * libhal_device_property_watch_all: 2730*2912Sartem * @ctx: the context for the connection to hald 2731*2912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL 2732*2912Sartem * 2733*2912Sartem * Watch all devices, ie. the device_property_changed callback is 2734*2912Sartem * invoked when the properties on any device changes. 2735*2912Sartem * 2736*2912Sartem * Returns: TRUE only if the operation succeeded 2737*2912Sartem */ 2738*2912Sartem dbus_bool_t 2739*2912Sartem libhal_device_property_watch_all (LibHalContext *ctx, DBusError *error) 2740*2912Sartem { 2741*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); 2742*2912Sartem 2743*2912Sartem dbus_bus_add_match (ctx->connection, 2744*2912Sartem "type='signal'," 2745*2912Sartem "interface='org.freedesktop.Hal.Device'," 2746*2912Sartem "sender='org.freedesktop.Hal'", error); 2747*2912Sartem if (dbus_error_is_set (error)) { 2748*2912Sartem return FALSE; 2749*2912Sartem } 2750*2912Sartem return TRUE; 2751*2912Sartem } 2752*2912Sartem 2753*2912Sartem 2754*2912Sartem /** 2755*2912Sartem * libhal_device_add_property_watch: 2756*2912Sartem * @ctx: the context for the connection to hald 2757*2912Sartem * @udi: the Unique Device Id 2758*2912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL 2759*2912Sartem * 2760*2912Sartem * Add a watch on a device, so the device_property_changed callback is 2761*2912Sartem * invoked when the properties on the given device changes. 2762*2912Sartem * 2763*2912Sartem * The application itself is responsible for deleting the watch, using 2764*2912Sartem * libhal_device_remove_property_watch, if the device is removed. 2765*2912Sartem * 2766*2912Sartem * Returns: TRUE only if the operation succeeded 2767*2912Sartem */ 2768*2912Sartem dbus_bool_t 2769*2912Sartem libhal_device_add_property_watch (LibHalContext *ctx, const char *udi, DBusError *error) 2770*2912Sartem { 2771*2912Sartem char buf[512]; 2772*2912Sartem 2773*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); 2774*2912Sartem 2775*2912Sartem snprintf (buf, 512, 2776*2912Sartem "type='signal'," 2777*2912Sartem "interface='org.freedesktop.Hal.Device'," 2778*2912Sartem "sender='org.freedesktop.Hal'," "path=%s", udi); 2779*2912Sartem 2780*2912Sartem dbus_bus_add_match (ctx->connection, buf, error); 2781*2912Sartem if (dbus_error_is_set (error)) { 2782*2912Sartem return FALSE; 2783*2912Sartem } 2784*2912Sartem return TRUE; 2785*2912Sartem } 2786*2912Sartem 2787*2912Sartem 2788*2912Sartem /** 2789*2912Sartem * libhal_device_remove_property_watch: 2790*2912Sartem * @ctx: the context for the connection to hald 2791*2912Sartem * @udi: the Unique Device Id 2792*2912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL 2793*2912Sartem * 2794*2912Sartem * Remove a watch on a device. 2795*2912Sartem * 2796*2912Sartem * Returns: TRUE only if the operation succeeded 2797*2912Sartem */ 2798*2912Sartem dbus_bool_t 2799*2912Sartem libhal_device_remove_property_watch (LibHalContext *ctx, const char *udi, DBusError *error) 2800*2912Sartem { 2801*2912Sartem char buf[512]; 2802*2912Sartem 2803*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); 2804*2912Sartem 2805*2912Sartem snprintf (buf, 512, 2806*2912Sartem "type='signal'," 2807*2912Sartem "interface='org.freedesktop.Hal.Device'," 2808*2912Sartem "sender='org.freedesktop.Hal'," "path=%s", udi); 2809*2912Sartem 2810*2912Sartem dbus_bus_remove_match (ctx->connection, buf, error); 2811*2912Sartem if (dbus_error_is_set (error)) { 2812*2912Sartem return FALSE; 2813*2912Sartem } 2814*2912Sartem return TRUE; 2815*2912Sartem } 2816*2912Sartem 2817*2912Sartem 2818*2912Sartem /** 2819*2912Sartem * libhal_ctx_new: 2820*2912Sartem * 2821*2912Sartem * Create a new LibHalContext 2822*2912Sartem * 2823*2912Sartem * Returns: a new uninitialized LibHalContext object 2824*2912Sartem */ 2825*2912Sartem LibHalContext * 2826*2912Sartem libhal_ctx_new (void) 2827*2912Sartem { 2828*2912Sartem LibHalContext *ctx; 2829*2912Sartem 2830*2912Sartem if (!libhal_already_initialized_once) { 2831*2912Sartem bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR); 2832*2912Sartem bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); 2833*2912Sartem 2834*2912Sartem libhal_already_initialized_once = TRUE; 2835*2912Sartem } 2836*2912Sartem 2837*2912Sartem ctx = calloc (1, sizeof (LibHalContext)); 2838*2912Sartem if (ctx == NULL) { 2839*2912Sartem fprintf (stderr, 2840*2912Sartem "%s %d : Failed to allocate %d bytes\n", 2841*2912Sartem __FILE__, __LINE__, sizeof (LibHalContext)); 2842*2912Sartem return NULL; 2843*2912Sartem } 2844*2912Sartem 2845*2912Sartem ctx->is_initialized = FALSE; 2846*2912Sartem ctx->is_shutdown = FALSE; 2847*2912Sartem ctx->connection = NULL; 2848*2912Sartem ctx->is_direct = FALSE; 2849*2912Sartem 2850*2912Sartem return ctx; 2851*2912Sartem } 2852*2912Sartem 2853*2912Sartem /** 2854*2912Sartem * libhal_ctx_set_cache: 2855*2912Sartem * @ctx: context to enable/disable cache for 2856*2912Sartem * @use_cache: whether or not to use cache 2857*2912Sartem * 2858*2912Sartem * Enable or disable caching. Note: Caching is not actually 2859*2912Sartem * implemented yet. 2860*2912Sartem * 2861*2912Sartem * Returns: TRUE if cache was successfully enabled/disabled, FALSE otherwise 2862*2912Sartem */ 2863*2912Sartem dbus_bool_t 2864*2912Sartem libhal_ctx_set_cache (LibHalContext *ctx, dbus_bool_t use_cache) 2865*2912Sartem { 2866*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); 2867*2912Sartem 2868*2912Sartem ctx->cache_enabled = use_cache; 2869*2912Sartem return TRUE; 2870*2912Sartem } 2871*2912Sartem 2872*2912Sartem /** 2873*2912Sartem * libhal_ctx_set_dbus_connection: 2874*2912Sartem * @ctx: context to set connection for 2875*2912Sartem * @conn: DBus connection to use 2876*2912Sartem * 2877*2912Sartem * Set DBus connection to use to talk to hald. 2878*2912Sartem * 2879*2912Sartem * Returns: TRUE if connection was successfully set, FALSE otherwise 2880*2912Sartem */ 2881*2912Sartem dbus_bool_t 2882*2912Sartem libhal_ctx_set_dbus_connection (LibHalContext *ctx, DBusConnection *conn) 2883*2912Sartem { 2884*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); 2885*2912Sartem 2886*2912Sartem if (conn == NULL) 2887*2912Sartem return FALSE; 2888*2912Sartem 2889*2912Sartem ctx->connection = conn; 2890*2912Sartem return TRUE; 2891*2912Sartem } 2892*2912Sartem 2893*2912Sartem /** 2894*2912Sartem * libhal_ctx_get_dbus_connection: 2895*2912Sartem * @ctx: context to get connection for 2896*2912Sartem * 2897*2912Sartem * Get DBus connection used for talking to hald. 2898*2912Sartem * 2899*2912Sartem * Returns: DBus connection to use or NULL 2900*2912Sartem */ 2901*2912Sartem DBusConnection * 2902*2912Sartem libhal_ctx_get_dbus_connection (LibHalContext *ctx) 2903*2912Sartem { 2904*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); 2905*2912Sartem 2906*2912Sartem return ctx->connection; 2907*2912Sartem } 2908*2912Sartem 2909*2912Sartem 2910*2912Sartem /** 2911*2912Sartem * libhal_ctx_init: 2912*2912Sartem * @ctx: Context for connection to hald (D-BUS connection should be set with libhal_ctx_set_dbus_connection) 2913*2912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL 2914*2912Sartem * 2915*2912Sartem * Initialize the connection to hald. 2916*2912Sartem * 2917*2912Sartem * Returns: TRUE if initialization succeeds, FALSE otherwise 2918*2912Sartem */ 2919*2912Sartem dbus_bool_t 2920*2912Sartem libhal_ctx_init (LibHalContext *ctx, DBusError *error) 2921*2912Sartem { 2922*2912Sartem DBusError _error; 2923*2912Sartem dbus_bool_t hald_exists; 2924*2912Sartem 2925*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); 2926*2912Sartem 2927*2912Sartem if (ctx->connection == NULL) 2928*2912Sartem return FALSE; 2929*2912Sartem 2930*2912Sartem dbus_error_init (&_error); 2931*2912Sartem hald_exists = dbus_bus_name_has_owner (ctx->connection, "org.freedesktop.Hal", &_error); 2932*2912Sartem dbus_move_error (&_error, error); 2933*2912Sartem if (error != NULL && dbus_error_is_set (error)) { 2934*2912Sartem return FALSE; 2935*2912Sartem } 2936*2912Sartem 2937*2912Sartem if (!hald_exists) { 2938*2912Sartem return FALSE; 2939*2912Sartem } 2940*2912Sartem 2941*2912Sartem 2942*2912Sartem if (!dbus_connection_add_filter (ctx->connection, filter_func, ctx, NULL)) { 2943*2912Sartem return FALSE; 2944*2912Sartem } 2945*2912Sartem 2946*2912Sartem dbus_bus_add_match (ctx->connection, 2947*2912Sartem "type='signal'," 2948*2912Sartem "interface='org.freedesktop.Hal.Manager'," 2949*2912Sartem "sender='org.freedesktop.Hal'," 2950*2912Sartem "path='/org/freedesktop/Hal/Manager'", &_error); 2951*2912Sartem dbus_move_error (&_error, error); 2952*2912Sartem if (error != NULL && dbus_error_is_set (error)) { 2953*2912Sartem return FALSE; 2954*2912Sartem } 2955*2912Sartem ctx->is_initialized = TRUE; 2956*2912Sartem ctx->is_direct = FALSE; 2957*2912Sartem 2958*2912Sartem return TRUE; 2959*2912Sartem } 2960*2912Sartem 2961*2912Sartem /** 2962*2912Sartem * libhal_ctx_init_direct: 2963*2912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL 2964*2912Sartem * 2965*2912Sartem * Create an already initialized connection to hald. This function should only be used by HAL helpers. 2966*2912Sartem * 2967*2912Sartem * Returns: A pointer to an already initialized LibHalContext 2968*2912Sartem */ 2969*2912Sartem LibHalContext * 2970*2912Sartem libhal_ctx_init_direct (DBusError *error) 2971*2912Sartem { 2972*2912Sartem char *hald_addr; 2973*2912Sartem LibHalContext *ctx; 2974*2912Sartem DBusError _error; 2975*2912Sartem 2976*2912Sartem ctx = libhal_ctx_new (); 2977*2912Sartem if (ctx == NULL) 2978*2912Sartem goto out; 2979*2912Sartem 2980*2912Sartem if (((hald_addr = getenv ("HALD_DIRECT_ADDR"))) == NULL) { 2981*2912Sartem libhal_ctx_free (ctx); 2982*2912Sartem ctx = NULL; 2983*2912Sartem goto out; 2984*2912Sartem } 2985*2912Sartem 2986*2912Sartem dbus_error_init (&_error); 2987*2912Sartem ctx->connection = dbus_connection_open (hald_addr, &_error); 2988*2912Sartem dbus_move_error (&_error, error); 2989*2912Sartem if (error != NULL && dbus_error_is_set (error)) { 2990*2912Sartem libhal_ctx_free (ctx); 2991*2912Sartem ctx = NULL; 2992*2912Sartem goto out; 2993*2912Sartem } 2994*2912Sartem 2995*2912Sartem ctx->is_initialized = TRUE; 2996*2912Sartem ctx->is_direct = TRUE; 2997*2912Sartem 2998*2912Sartem out: 2999*2912Sartem return ctx; 3000*2912Sartem } 3001*2912Sartem 3002*2912Sartem /** 3003*2912Sartem * libhal_ctx_shutdown: 3004*2912Sartem * @ctx: the context for the connection to hald 3005*2912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL 3006*2912Sartem * 3007*2912Sartem * Shut down a connection to hald. 3008*2912Sartem * 3009*2912Sartem * Returns: TRUE if connection successfully shut down, FALSE otherwise 3010*2912Sartem */ 3011*2912Sartem dbus_bool_t 3012*2912Sartem libhal_ctx_shutdown (LibHalContext *ctx, DBusError *error) 3013*2912Sartem { 3014*2912Sartem DBusError myerror; 3015*2912Sartem 3016*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); 3017*2912Sartem 3018*2912Sartem if (ctx->is_direct) { 3019*2912Sartem /* for some reason dbus_connection_set_exit_on_disconnect doesn't work yet so don't unref */ 3020*2912Sartem /*dbus_connection_unref (ctx->connection);*/ 3021*2912Sartem } else { 3022*2912Sartem dbus_error_init (&myerror); 3023*2912Sartem dbus_bus_remove_match (ctx->connection, 3024*2912Sartem "type='signal'," 3025*2912Sartem "interface='org.freedesktop.Hal.Manager'," 3026*2912Sartem "sender='org.freedesktop.Hal'," 3027*2912Sartem "path='/org/freedesktop/Hal/Manager'", &myerror); 3028*2912Sartem if (dbus_error_is_set (&myerror)) { 3029*2912Sartem dbus_move_error (&myerror, error); 3030*2912Sartem fprintf (stderr, "%s %d : Error unsubscribing to signals, error=%s\n", 3031*2912Sartem __FILE__, __LINE__, error->message); 3032*2912Sartem /** @todo clean up */ 3033*2912Sartem } 3034*2912Sartem 3035*2912Sartem /* TODO: remove other matches */ 3036*2912Sartem 3037*2912Sartem dbus_connection_remove_filter (ctx->connection, filter_func, ctx); 3038*2912Sartem } 3039*2912Sartem 3040*2912Sartem ctx->is_initialized = FALSE; 3041*2912Sartem 3042*2912Sartem return TRUE; 3043*2912Sartem } 3044*2912Sartem 3045*2912Sartem /** 3046*2912Sartem * libhal_ctx_free: 3047*2912Sartem * @ctx: pointer to a LibHalContext 3048*2912Sartem * 3049*2912Sartem * Free a LibHalContext resource. 3050*2912Sartem * 3051*2912Sartem * Returns: TRUE 3052*2912Sartem */ 3053*2912Sartem dbus_bool_t 3054*2912Sartem libhal_ctx_free (LibHalContext *ctx) 3055*2912Sartem { 3056*2912Sartem free (ctx); 3057*2912Sartem return TRUE; 3058*2912Sartem } 3059*2912Sartem 3060*2912Sartem /** 3061*2912Sartem * libhal_ctx_set_device_added: 3062*2912Sartem * @ctx: the context for the connection to hald 3063*2912Sartem * @callback: the function to call when a device is added 3064*2912Sartem * 3065*2912Sartem * Set the callback for when a device is added 3066*2912Sartem * 3067*2912Sartem * Returns: TRUE if callback was successfully set, FALSE otherwise 3068*2912Sartem */ 3069*2912Sartem dbus_bool_t 3070*2912Sartem libhal_ctx_set_device_added (LibHalContext *ctx, LibHalDeviceAdded callback) 3071*2912Sartem { 3072*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); 3073*2912Sartem 3074*2912Sartem ctx->device_added = callback; 3075*2912Sartem return TRUE; 3076*2912Sartem } 3077*2912Sartem 3078*2912Sartem /** 3079*2912Sartem * libhal_ctx_set_device_removed: 3080*2912Sartem * @ctx: the context for the connection to hald 3081*2912Sartem * @callback: the function to call when a device is removed 3082*2912Sartem * 3083*2912Sartem * Set the callback for when a device is removed. 3084*2912Sartem * 3085*2912Sartem * Returns: TRUE if callback was successfully set, FALSE otherwise 3086*2912Sartem */ 3087*2912Sartem dbus_bool_t 3088*2912Sartem libhal_ctx_set_device_removed (LibHalContext *ctx, LibHalDeviceRemoved callback) 3089*2912Sartem { 3090*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); 3091*2912Sartem 3092*2912Sartem ctx->device_removed = callback; 3093*2912Sartem return TRUE; 3094*2912Sartem } 3095*2912Sartem 3096*2912Sartem /** 3097*2912Sartem * libhal_ctx_set_device_new_capability: 3098*2912Sartem * @ctx: the context for the connection to hald 3099*2912Sartem * @callback: the function to call when a device gains a new capability 3100*2912Sartem * 3101*2912Sartem * Set the callback for when a device gains a new capability. 3102*2912Sartem * 3103*2912Sartem * Returns: TRUE if callback was successfully set, FALSE otherwise 3104*2912Sartem */ 3105*2912Sartem dbus_bool_t 3106*2912Sartem libhal_ctx_set_device_new_capability (LibHalContext *ctx, LibHalDeviceNewCapability callback) 3107*2912Sartem { 3108*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); 3109*2912Sartem 3110*2912Sartem ctx->device_new_capability = callback; 3111*2912Sartem return TRUE; 3112*2912Sartem } 3113*2912Sartem 3114*2912Sartem /** 3115*2912Sartem * libhal_ctx_set_device_lost_capability: 3116*2912Sartem * @ctx: the context for the connection to hald 3117*2912Sartem * @callback: the function to call when a device loses a capability 3118*2912Sartem * 3119*2912Sartem * Set the callback for when a device loses a capability 3120*2912Sartem * 3121*2912Sartem * Returns: TRUE if callback was successfully set, FALSE otherwise 3122*2912Sartem */ 3123*2912Sartem dbus_bool_t 3124*2912Sartem libhal_ctx_set_device_lost_capability (LibHalContext *ctx, LibHalDeviceLostCapability callback) 3125*2912Sartem { 3126*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); 3127*2912Sartem 3128*2912Sartem ctx->device_lost_capability = callback; 3129*2912Sartem return TRUE; 3130*2912Sartem } 3131*2912Sartem 3132*2912Sartem /** 3133*2912Sartem * libhal_ctx_set_device_property_modified: 3134*2912Sartem * @ctx: the context for the connection to hald 3135*2912Sartem * @callback: the function to call when a property is modified on a device 3136*2912Sartem * 3137*2912Sartem * Set the callback for when a property is modified on a device. 3138*2912Sartem * 3139*2912Sartem * Returns: TRUE if callback was successfully set, FALSE otherwise 3140*2912Sartem */ 3141*2912Sartem dbus_bool_t 3142*2912Sartem libhal_ctx_set_device_property_modified (LibHalContext *ctx, LibHalDevicePropertyModified callback) 3143*2912Sartem { 3144*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); 3145*2912Sartem 3146*2912Sartem ctx->device_property_modified = callback; 3147*2912Sartem return TRUE; 3148*2912Sartem } 3149*2912Sartem 3150*2912Sartem /** 3151*2912Sartem * libhal_ctx_set_device_condition: 3152*2912Sartem * @ctx: the context for the connection to hald 3153*2912Sartem * @callback: the function to call when a device emits a condition 3154*2912Sartem * 3155*2912Sartem * Set the callback for when a device emits a condition 3156*2912Sartem * 3157*2912Sartem * Returns: TRUE if callback was successfully set, FALSE otherwise 3158*2912Sartem */ 3159*2912Sartem dbus_bool_t 3160*2912Sartem libhal_ctx_set_device_condition (LibHalContext *ctx, LibHalDeviceCondition callback) 3161*2912Sartem { 3162*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); 3163*2912Sartem 3164*2912Sartem ctx->device_condition = callback; 3165*2912Sartem return TRUE; 3166*2912Sartem } 3167*2912Sartem 3168*2912Sartem /** 3169*2912Sartem * libhal_string_array_length: 3170*2912Sartem * @str_array: array of strings to consider 3171*2912Sartem * 3172*2912Sartem * Get the length of an array of strings. 3173*2912Sartem * 3174*2912Sartem * Returns: Number of strings in array 3175*2912Sartem */ 3176*2912Sartem unsigned int 3177*2912Sartem libhal_string_array_length (char **str_array) 3178*2912Sartem { 3179*2912Sartem unsigned int i; 3180*2912Sartem 3181*2912Sartem if (str_array == NULL) 3182*2912Sartem return 0; 3183*2912Sartem 3184*2912Sartem for (i = 0; str_array[i] != NULL; i++) 3185*2912Sartem ; 3186*2912Sartem 3187*2912Sartem return i; 3188*2912Sartem } 3189*2912Sartem 3190*2912Sartem 3191*2912Sartem /** 3192*2912Sartem * libhal_device_rescan: 3193*2912Sartem * @ctx: the context for the connection to hald 3194*2912Sartem * @udi: the Unique id of device 3195*2912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL 3196*2912Sartem * 3197*2912Sartem * TODO document me. 3198*2912Sartem * 3199*2912Sartem * Returns: Whether the operation succeeded 3200*2912Sartem */ 3201*2912Sartem dbus_bool_t 3202*2912Sartem libhal_device_rescan (LibHalContext *ctx, const char *udi, DBusError *error) 3203*2912Sartem { 3204*2912Sartem DBusMessage *message; 3205*2912Sartem DBusMessageIter reply_iter; 3206*2912Sartem DBusMessage *reply; 3207*2912Sartem dbus_bool_t result; 3208*2912Sartem 3209*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); 3210*2912Sartem 3211*2912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, 3212*2912Sartem "org.freedesktop.Hal.Device", 3213*2912Sartem "Rescan"); 3214*2912Sartem 3215*2912Sartem if (message == NULL) { 3216*2912Sartem fprintf (stderr, 3217*2912Sartem "%s %d : Couldn't allocate D-BUS message\n", 3218*2912Sartem __FILE__, __LINE__); 3219*2912Sartem return FALSE; 3220*2912Sartem } 3221*2912Sartem 3222*2912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection, 3223*2912Sartem message, -1, 3224*2912Sartem error); 3225*2912Sartem 3226*2912Sartem if (dbus_error_is_set (error)) { 3227*2912Sartem dbus_message_unref (message); 3228*2912Sartem return FALSE; 3229*2912Sartem } 3230*2912Sartem 3231*2912Sartem dbus_message_unref (message); 3232*2912Sartem 3233*2912Sartem if (reply == NULL) 3234*2912Sartem return FALSE; 3235*2912Sartem 3236*2912Sartem dbus_message_iter_init (reply, &reply_iter); 3237*2912Sartem if (dbus_message_iter_get_arg_type (&reply_iter) != 3238*2912Sartem DBUS_TYPE_BOOLEAN) { 3239*2912Sartem dbus_message_unref (message); 3240*2912Sartem dbus_message_unref (reply); 3241*2912Sartem return FALSE; 3242*2912Sartem } 3243*2912Sartem dbus_message_iter_get_basic (&reply_iter, &result); 3244*2912Sartem 3245*2912Sartem dbus_message_unref (reply); 3246*2912Sartem 3247*2912Sartem return result; 3248*2912Sartem } 3249*2912Sartem 3250*2912Sartem /** 3251*2912Sartem * libhal_device_reprobe: 3252*2912Sartem * @ctx: the context for the connection to hald 3253*2912Sartem * @udi: the Unique id of device 3254*2912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL 3255*2912Sartem * 3256*2912Sartem * TODO document me. 3257*2912Sartem * 3258*2912Sartem * Returns: Whether the operation succeeded 3259*2912Sartem */ 3260*2912Sartem dbus_bool_t 3261*2912Sartem libhal_device_reprobe (LibHalContext *ctx, const char *udi, DBusError *error) 3262*2912Sartem { 3263*2912Sartem DBusMessage *message; 3264*2912Sartem DBusMessageIter reply_iter; 3265*2912Sartem DBusMessage *reply; 3266*2912Sartem dbus_bool_t result; 3267*2912Sartem 3268*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); 3269*2912Sartem 3270*2912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", 3271*2912Sartem udi, 3272*2912Sartem "org.freedesktop.Hal.Device", 3273*2912Sartem "Reprobe"); 3274*2912Sartem 3275*2912Sartem if (message == NULL) { 3276*2912Sartem fprintf (stderr, 3277*2912Sartem "%s %d : Couldn't allocate D-BUS message\n", 3278*2912Sartem __FILE__, __LINE__); 3279*2912Sartem return FALSE; 3280*2912Sartem } 3281*2912Sartem 3282*2912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection, 3283*2912Sartem message, -1, 3284*2912Sartem error); 3285*2912Sartem 3286*2912Sartem if (dbus_error_is_set (error)) { 3287*2912Sartem dbus_message_unref (message); 3288*2912Sartem return FALSE; 3289*2912Sartem } 3290*2912Sartem 3291*2912Sartem dbus_message_unref (message); 3292*2912Sartem 3293*2912Sartem if (reply == NULL) 3294*2912Sartem return FALSE; 3295*2912Sartem 3296*2912Sartem dbus_message_iter_init (reply, &reply_iter); 3297*2912Sartem if (dbus_message_iter_get_arg_type (&reply_iter) != 3298*2912Sartem DBUS_TYPE_BOOLEAN) { 3299*2912Sartem dbus_message_unref (message); 3300*2912Sartem dbus_message_unref (reply); 3301*2912Sartem return FALSE; 3302*2912Sartem } 3303*2912Sartem dbus_message_iter_get_basic (&reply_iter, &result); 3304*2912Sartem 3305*2912Sartem dbus_message_unref (reply); 3306*2912Sartem 3307*2912Sartem return result; 3308*2912Sartem } 3309*2912Sartem 3310*2912Sartem /** 3311*2912Sartem * libhal_device_emit_condition: 3312*2912Sartem * @ctx: the context for the connection to hald 3313*2912Sartem * @udi: the Unique Device Id 3314*2912Sartem * @condition_name: user-readable name of condition 3315*2912Sartem * @condition_details: user-readable details of condition 3316*2912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL 3317*2912Sartem * 3318*2912Sartem * Emit a condition from a device. Can only be used from hald helpers. 3319*2912Sartem * 3320*2912Sartem * Returns: TRUE if condition successfully emitted, 3321*2912Sartem * FALSE otherwise 3322*2912Sartem */ 3323*2912Sartem dbus_bool_t libhal_device_emit_condition (LibHalContext *ctx, 3324*2912Sartem const char *udi, 3325*2912Sartem const char *condition_name, 3326*2912Sartem const char *condition_details, 3327*2912Sartem DBusError *error) 3328*2912Sartem { 3329*2912Sartem DBusMessage *message; 3330*2912Sartem DBusMessageIter iter; 3331*2912Sartem DBusMessageIter reply_iter; 3332*2912Sartem DBusMessage *reply; 3333*2912Sartem dbus_bool_t result; 3334*2912Sartem 3335*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); 3336*2912Sartem 3337*2912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", 3338*2912Sartem udi, 3339*2912Sartem "org.freedesktop.Hal.Device", 3340*2912Sartem "EmitCondition"); 3341*2912Sartem 3342*2912Sartem if (message == NULL) { 3343*2912Sartem fprintf (stderr, 3344*2912Sartem "%s %d : Couldn't allocate D-BUS message\n", 3345*2912Sartem __FILE__, __LINE__); 3346*2912Sartem return FALSE; 3347*2912Sartem } 3348*2912Sartem 3349*2912Sartem dbus_message_iter_init_append (message, &iter); 3350*2912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &condition_name); 3351*2912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &condition_details); 3352*2912Sartem 3353*2912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection, 3354*2912Sartem message, -1, 3355*2912Sartem error); 3356*2912Sartem 3357*2912Sartem if (dbus_error_is_set (error)) { 3358*2912Sartem dbus_message_unref (message); 3359*2912Sartem return FALSE; 3360*2912Sartem } 3361*2912Sartem 3362*2912Sartem dbus_message_unref (message); 3363*2912Sartem 3364*2912Sartem if (reply == NULL) 3365*2912Sartem return FALSE; 3366*2912Sartem 3367*2912Sartem dbus_message_iter_init (reply, &reply_iter); 3368*2912Sartem if (dbus_message_iter_get_arg_type (&reply_iter) != 3369*2912Sartem DBUS_TYPE_BOOLEAN) { 3370*2912Sartem dbus_message_unref (message); 3371*2912Sartem dbus_message_unref (reply); 3372*2912Sartem return FALSE; 3373*2912Sartem } 3374*2912Sartem dbus_message_iter_get_basic (&reply_iter, &result); 3375*2912Sartem 3376*2912Sartem dbus_message_unref (reply); 3377*2912Sartem 3378*2912Sartem return result; 3379*2912Sartem } 3380*2912Sartem 3381*2912Sartem /** 3382*2912Sartem * libhal_device_addon_is_ready: 3383*2912Sartem * @ctx: the context for the connection to hald 3384*2912Sartem * @udi: the Unique Device Id 3385*2912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL 3386*2912Sartem * 3387*2912Sartem * HAL addon's must call this method when they are done initializing the device object. The HAL 3388*2912Sartem * daemon will wait for all addon's to call this. 3389*2912Sartem * 3390*2912Sartem * Can only be used from hald helpers. 3391*2912Sartem * 3392*2912Sartem * Returns: TRUE if the HAL daemon received the message, FALSE otherwise 3393*2912Sartem */ 3394*2912Sartem dbus_bool_t 3395*2912Sartem libhal_device_addon_is_ready (LibHalContext *ctx, const char *udi, DBusError *error) 3396*2912Sartem { 3397*2912Sartem DBusMessage *message; 3398*2912Sartem DBusMessageIter iter; 3399*2912Sartem DBusMessageIter reply_iter; 3400*2912Sartem DBusMessage *reply; 3401*2912Sartem dbus_bool_t result; 3402*2912Sartem 3403*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); 3404*2912Sartem 3405*2912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", 3406*2912Sartem udi, 3407*2912Sartem "org.freedesktop.Hal.Device", 3408*2912Sartem "AddonIsReady"); 3409*2912Sartem 3410*2912Sartem if (message == NULL) { 3411*2912Sartem fprintf (stderr, 3412*2912Sartem "%s %d : Couldn't allocate D-BUS message\n", 3413*2912Sartem __FILE__, __LINE__); 3414*2912Sartem return FALSE; 3415*2912Sartem } 3416*2912Sartem 3417*2912Sartem dbus_message_iter_init_append (message, &iter); 3418*2912Sartem 3419*2912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection, 3420*2912Sartem message, -1, 3421*2912Sartem error); 3422*2912Sartem 3423*2912Sartem if (dbus_error_is_set (error)) { 3424*2912Sartem dbus_message_unref (message); 3425*2912Sartem return FALSE; 3426*2912Sartem } 3427*2912Sartem 3428*2912Sartem dbus_message_unref (message); 3429*2912Sartem 3430*2912Sartem if (reply == NULL) 3431*2912Sartem return FALSE; 3432*2912Sartem 3433*2912Sartem dbus_message_iter_init (reply, &reply_iter); 3434*2912Sartem if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_BOOLEAN) { 3435*2912Sartem dbus_message_unref (message); 3436*2912Sartem dbus_message_unref (reply); 3437*2912Sartem return FALSE; 3438*2912Sartem } 3439*2912Sartem dbus_message_iter_get_basic (&reply_iter, &result); 3440*2912Sartem 3441*2912Sartem dbus_message_unref (reply); 3442*2912Sartem return result; 3443*2912Sartem } 3444*2912Sartem 3445*2912Sartem /** 3446*2912Sartem * libhal_device_claim_interface: 3447*2912Sartem * @ctx: the context for the connection to hald 3448*2912Sartem * @udi: the Unique Device Id 3449*2912Sartem * @interface_name: Name of interface to claim, e.g. org.freedesktop.Hal.Device.FoobarKindOfThing 3450*2912Sartem * @introspection_xml: Introspection XML containing what would be inside the interface XML tag 3451*2912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL 3452*2912Sartem * 3453*2912Sartem * Claim an interface for a device. All messages to this interface 3454*2912Sartem * will be forwarded to the helper. Can only be used from hald 3455*2912Sartem * helpers. 3456*2912Sartem * 3457*2912Sartem * Returns: TRUE if interface was claimed, FALSE otherwise 3458*2912Sartem */ 3459*2912Sartem dbus_bool_t 3460*2912Sartem libhal_device_claim_interface (LibHalContext *ctx, 3461*2912Sartem const char *udi, 3462*2912Sartem const char *interface_name, 3463*2912Sartem const char *introspection_xml, 3464*2912Sartem DBusError *error) 3465*2912Sartem { 3466*2912Sartem DBusMessage *message; 3467*2912Sartem DBusMessageIter iter; 3468*2912Sartem DBusMessageIter reply_iter; 3469*2912Sartem DBusMessage *reply; 3470*2912Sartem dbus_bool_t result; 3471*2912Sartem 3472*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); 3473*2912Sartem 3474*2912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", 3475*2912Sartem udi, 3476*2912Sartem "org.freedesktop.Hal.Device", 3477*2912Sartem "ClaimInterface"); 3478*2912Sartem 3479*2912Sartem if (message == NULL) { 3480*2912Sartem fprintf (stderr, 3481*2912Sartem "%s %d : Couldn't allocate D-BUS message\n", 3482*2912Sartem __FILE__, __LINE__); 3483*2912Sartem return FALSE; 3484*2912Sartem } 3485*2912Sartem 3486*2912Sartem dbus_message_iter_init_append (message, &iter); 3487*2912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &interface_name); 3488*2912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &introspection_xml); 3489*2912Sartem 3490*2912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection, 3491*2912Sartem message, -1, 3492*2912Sartem error); 3493*2912Sartem 3494*2912Sartem if (dbus_error_is_set (error)) { 3495*2912Sartem dbus_message_unref (message); 3496*2912Sartem return FALSE; 3497*2912Sartem } 3498*2912Sartem 3499*2912Sartem dbus_message_unref (message); 3500*2912Sartem 3501*2912Sartem if (reply == NULL) 3502*2912Sartem return FALSE; 3503*2912Sartem 3504*2912Sartem dbus_message_iter_init (reply, &reply_iter); 3505*2912Sartem if (dbus_message_iter_get_arg_type (&reply_iter) != 3506*2912Sartem DBUS_TYPE_BOOLEAN) { 3507*2912Sartem dbus_message_unref (message); 3508*2912Sartem dbus_message_unref (reply); 3509*2912Sartem return FALSE; 3510*2912Sartem } 3511*2912Sartem dbus_message_iter_get_basic (&reply_iter, &result); 3512*2912Sartem 3513*2912Sartem dbus_message_unref (reply); 3514*2912Sartem 3515*2912Sartem return result; 3516*2912Sartem } 3517*2912Sartem 3518*2912Sartem 3519*2912Sartem 3520*2912Sartem struct LibHalChangeSetElement_s; 3521*2912Sartem 3522*2912Sartem typedef struct LibHalChangeSetElement_s LibHalChangeSetElement; 3523*2912Sartem 3524*2912Sartem struct LibHalChangeSetElement_s { 3525*2912Sartem char *key; 3526*2912Sartem int change_type; 3527*2912Sartem union { 3528*2912Sartem char *val_str; 3529*2912Sartem dbus_int32_t val_int; 3530*2912Sartem dbus_uint64_t val_uint64; 3531*2912Sartem double val_double; 3532*2912Sartem dbus_bool_t val_bool; 3533*2912Sartem char **val_strlist; 3534*2912Sartem } value; 3535*2912Sartem LibHalChangeSetElement *next; 3536*2912Sartem LibHalChangeSetElement *prev; 3537*2912Sartem }; 3538*2912Sartem 3539*2912Sartem struct LibHalChangeSet_s { 3540*2912Sartem char *udi; 3541*2912Sartem LibHalChangeSetElement *head; 3542*2912Sartem LibHalChangeSetElement *tail; 3543*2912Sartem }; 3544*2912Sartem 3545*2912Sartem /** 3546*2912Sartem * libhal_device_new_changeset: 3547*2912Sartem * @udi: unique device identifier 3548*2912Sartem * 3549*2912Sartem * Request a new changeset object. Used for changing multiple properties at once. Useful when 3550*2912Sartem * performance is critical and also for atomically updating several properties. 3551*2912Sartem * 3552*2912Sartem * Returns: A new changeset object or NULL on error 3553*2912Sartem */ 3554*2912Sartem LibHalChangeSet * 3555*2912Sartem libhal_device_new_changeset (const char *udi) 3556*2912Sartem { 3557*2912Sartem LibHalChangeSet *changeset; 3558*2912Sartem 3559*2912Sartem changeset = calloc (1, sizeof (LibHalChangeSet)); 3560*2912Sartem if (changeset == NULL) 3561*2912Sartem goto out; 3562*2912Sartem 3563*2912Sartem changeset->udi = strdup (udi); 3564*2912Sartem if (changeset->udi == NULL) { 3565*2912Sartem free (changeset); 3566*2912Sartem changeset = NULL; 3567*2912Sartem goto out; 3568*2912Sartem } 3569*2912Sartem 3570*2912Sartem changeset->head = NULL; 3571*2912Sartem changeset->tail = NULL; 3572*2912Sartem 3573*2912Sartem out: 3574*2912Sartem return changeset; 3575*2912Sartem } 3576*2912Sartem 3577*2912Sartem static void 3578*2912Sartem libhal_changeset_append (LibHalChangeSet *changeset, LibHalChangeSetElement *elem) 3579*2912Sartem { 3580*2912Sartem if (changeset->head == NULL) { 3581*2912Sartem changeset->head = elem; 3582*2912Sartem changeset->tail = elem; 3583*2912Sartem elem->next = NULL; 3584*2912Sartem elem->prev = NULL; 3585*2912Sartem } else { 3586*2912Sartem elem->prev = changeset->tail; 3587*2912Sartem elem->next = NULL; 3588*2912Sartem elem->prev->next = elem; 3589*2912Sartem changeset->tail = elem; 3590*2912Sartem } 3591*2912Sartem } 3592*2912Sartem 3593*2912Sartem 3594*2912Sartem /** 3595*2912Sartem * libhal_device_set_property_string: 3596*2912Sartem * @changeset: the changeset 3597*2912Sartem * @key: key of property 3598*2912Sartem * @value: the value to set 3599*2912Sartem * 3600*2912Sartem * Set a property. 3601*2912Sartem * 3602*2912Sartem * Returns: FALSE on OOM 3603*2912Sartem */ 3604*2912Sartem dbus_bool_t 3605*2912Sartem libhal_changeset_set_property_string (LibHalChangeSet *changeset, const char *key, const char *value) 3606*2912Sartem { 3607*2912Sartem LibHalChangeSetElement *elem; 3608*2912Sartem 3609*2912Sartem elem = calloc (1, sizeof (LibHalChangeSetElement)); 3610*2912Sartem if (elem == NULL) 3611*2912Sartem goto out; 3612*2912Sartem elem->key = strdup (key); 3613*2912Sartem if (elem->key == NULL) { 3614*2912Sartem free (elem); 3615*2912Sartem elem = NULL; 3616*2912Sartem goto out; 3617*2912Sartem } 3618*2912Sartem 3619*2912Sartem elem->change_type = LIBHAL_PROPERTY_TYPE_STRING; 3620*2912Sartem elem->value.val_str = strdup (value); 3621*2912Sartem if (elem->value.val_str == NULL) { 3622*2912Sartem free (elem->key); 3623*2912Sartem free (elem); 3624*2912Sartem elem = NULL; 3625*2912Sartem goto out; 3626*2912Sartem } 3627*2912Sartem 3628*2912Sartem libhal_changeset_append (changeset, elem); 3629*2912Sartem out: 3630*2912Sartem return elem != NULL; 3631*2912Sartem } 3632*2912Sartem 3633*2912Sartem /** 3634*2912Sartem * libhal_device_set_property_int: 3635*2912Sartem * @changeset: the changeset 3636*2912Sartem * @key: key of property 3637*2912Sartem * @value: the value to set 3638*2912Sartem * 3639*2912Sartem * Set a property. 3640*2912Sartem * 3641*2912Sartem * Returns: FALSE on OOM 3642*2912Sartem */ 3643*2912Sartem dbus_bool_t 3644*2912Sartem libhal_changeset_set_property_int (LibHalChangeSet *changeset, const char *key, dbus_int32_t value) 3645*2912Sartem { 3646*2912Sartem LibHalChangeSetElement *elem; 3647*2912Sartem 3648*2912Sartem elem = calloc (1, sizeof (LibHalChangeSetElement)); 3649*2912Sartem if (elem == NULL) 3650*2912Sartem goto out; 3651*2912Sartem elem->key = strdup (key); 3652*2912Sartem if (elem->key == NULL) { 3653*2912Sartem free (elem); 3654*2912Sartem elem = NULL; 3655*2912Sartem goto out; 3656*2912Sartem } 3657*2912Sartem 3658*2912Sartem elem->change_type = LIBHAL_PROPERTY_TYPE_INT32; 3659*2912Sartem elem->value.val_int = value; 3660*2912Sartem 3661*2912Sartem libhal_changeset_append (changeset, elem); 3662*2912Sartem out: 3663*2912Sartem return elem != NULL; 3664*2912Sartem } 3665*2912Sartem 3666*2912Sartem /** 3667*2912Sartem * libhal_device_set_property_uint64: 3668*2912Sartem * @changeset: the changeset 3669*2912Sartem * @key: key of property 3670*2912Sartem * @value: the value to set 3671*2912Sartem * 3672*2912Sartem * Set a property. 3673*2912Sartem * 3674*2912Sartem * Returns: FALSE on OOM 3675*2912Sartem */ 3676*2912Sartem dbus_bool_t 3677*2912Sartem libhal_changeset_set_property_uint64 (LibHalChangeSet *changeset, const char *key, dbus_uint64_t value) 3678*2912Sartem { 3679*2912Sartem LibHalChangeSetElement *elem; 3680*2912Sartem 3681*2912Sartem elem = calloc (1, sizeof (LibHalChangeSetElement)); 3682*2912Sartem if (elem == NULL) 3683*2912Sartem goto out; 3684*2912Sartem elem->key = strdup (key); 3685*2912Sartem if (elem->key == NULL) { 3686*2912Sartem free (elem); 3687*2912Sartem elem = NULL; 3688*2912Sartem goto out; 3689*2912Sartem } 3690*2912Sartem 3691*2912Sartem elem->change_type = LIBHAL_PROPERTY_TYPE_UINT64; 3692*2912Sartem elem->value.val_uint64 = value; 3693*2912Sartem 3694*2912Sartem libhal_changeset_append (changeset, elem); 3695*2912Sartem out: 3696*2912Sartem return elem != NULL; 3697*2912Sartem } 3698*2912Sartem 3699*2912Sartem /** 3700*2912Sartem * libhal_device_set_property_double: 3701*2912Sartem * @changeset: the changeset 3702*2912Sartem * @key: key of property 3703*2912Sartem * @value: the value to set 3704*2912Sartem * 3705*2912Sartem * Set a property. 3706*2912Sartem * 3707*2912Sartem * Returns: FALSE on OOM 3708*2912Sartem */ 3709*2912Sartem dbus_bool_t 3710*2912Sartem libhal_changeset_set_property_double (LibHalChangeSet *changeset, const char *key, double value) 3711*2912Sartem { 3712*2912Sartem LibHalChangeSetElement *elem; 3713*2912Sartem 3714*2912Sartem elem = calloc (1, sizeof (LibHalChangeSetElement)); 3715*2912Sartem if (elem == NULL) 3716*2912Sartem goto out; 3717*2912Sartem elem->key = strdup (key); 3718*2912Sartem if (elem->key == NULL) { 3719*2912Sartem free (elem); 3720*2912Sartem elem = NULL; 3721*2912Sartem goto out; 3722*2912Sartem } 3723*2912Sartem 3724*2912Sartem elem->change_type = LIBHAL_PROPERTY_TYPE_DOUBLE; 3725*2912Sartem elem->value.val_double = value; 3726*2912Sartem 3727*2912Sartem libhal_changeset_append (changeset, elem); 3728*2912Sartem out: 3729*2912Sartem return elem != NULL; 3730*2912Sartem } 3731*2912Sartem 3732*2912Sartem /** 3733*2912Sartem * libhal_device_set_property_bool: 3734*2912Sartem * @changeset: the changeset 3735*2912Sartem * @key: key of property 3736*2912Sartem * @value: the value to set 3737*2912Sartem * 3738*2912Sartem * Set a property. 3739*2912Sartem * 3740*2912Sartem * Returns: FALSE on OOM 3741*2912Sartem */ 3742*2912Sartem dbus_bool_t 3743*2912Sartem libhal_changeset_set_property_bool (LibHalChangeSet *changeset, const char *key, dbus_bool_t value) 3744*2912Sartem { 3745*2912Sartem LibHalChangeSetElement *elem; 3746*2912Sartem 3747*2912Sartem elem = calloc (1, sizeof (LibHalChangeSetElement)); 3748*2912Sartem if (elem == NULL) 3749*2912Sartem goto out; 3750*2912Sartem elem->key = strdup (key); 3751*2912Sartem if (elem->key == NULL) { 3752*2912Sartem free (elem); 3753*2912Sartem elem = NULL; 3754*2912Sartem goto out; 3755*2912Sartem } 3756*2912Sartem 3757*2912Sartem elem->change_type = LIBHAL_PROPERTY_TYPE_BOOLEAN; 3758*2912Sartem elem->value.val_bool = value; 3759*2912Sartem 3760*2912Sartem libhal_changeset_append (changeset, elem); 3761*2912Sartem out: 3762*2912Sartem return elem != NULL; 3763*2912Sartem } 3764*2912Sartem 3765*2912Sartem /** 3766*2912Sartem * libhal_device_set_property_strlist: 3767*2912Sartem * @changeset: the changeset 3768*2912Sartem * @key: key of property 3769*2912Sartem * @value: the value to set - NULL terminated array of strings 3770*2912Sartem * 3771*2912Sartem * Set a property. 3772*2912Sartem * 3773*2912Sartem * Returns: FALSE on OOM 3774*2912Sartem */ 3775*2912Sartem dbus_bool_t 3776*2912Sartem libhal_changeset_set_property_strlist (LibHalChangeSet *changeset, const char *key, const char **value) 3777*2912Sartem { 3778*2912Sartem LibHalChangeSetElement *elem; 3779*2912Sartem char **value_copy; 3780*2912Sartem int len; 3781*2912Sartem int i, j; 3782*2912Sartem 3783*2912Sartem elem = calloc (1, sizeof (LibHalChangeSetElement)); 3784*2912Sartem if (elem == NULL) 3785*2912Sartem goto out; 3786*2912Sartem elem->key = strdup (key); 3787*2912Sartem if (elem->key == NULL) { 3788*2912Sartem free (elem); 3789*2912Sartem elem = NULL; 3790*2912Sartem goto out; 3791*2912Sartem } 3792*2912Sartem 3793*2912Sartem for (i = 0; value[i] != NULL; i++) 3794*2912Sartem ; 3795*2912Sartem len = i; 3796*2912Sartem 3797*2912Sartem value_copy = calloc (len + 1, sizeof (char *)); 3798*2912Sartem if (value_copy == NULL) { 3799*2912Sartem free (elem->key); 3800*2912Sartem free (elem); 3801*2912Sartem elem = NULL; 3802*2912Sartem goto out; 3803*2912Sartem } 3804*2912Sartem 3805*2912Sartem for (i = 0; i < len; i++) { 3806*2912Sartem value_copy[i] = strdup (value[i]); 3807*2912Sartem if (value_copy[i] == NULL) { 3808*2912Sartem for (j = 0; j < i; j++) { 3809*2912Sartem free (value_copy[j]); 3810*2912Sartem } 3811*2912Sartem free (value_copy); 3812*2912Sartem free (elem->key); 3813*2912Sartem free (elem); 3814*2912Sartem elem = NULL; 3815*2912Sartem goto out; 3816*2912Sartem } 3817*2912Sartem } 3818*2912Sartem value_copy[i] = NULL; 3819*2912Sartem 3820*2912Sartem elem->change_type = LIBHAL_PROPERTY_TYPE_STRLIST; 3821*2912Sartem elem->value.val_strlist = value_copy; 3822*2912Sartem 3823*2912Sartem libhal_changeset_append (changeset, elem); 3824*2912Sartem out: 3825*2912Sartem return elem != NULL; 3826*2912Sartem } 3827*2912Sartem 3828*2912Sartem /** 3829*2912Sartem * libhal_device_commit_changeset: 3830*2912Sartem * @ctx: the context for the connection to hald 3831*2912Sartem * @changeset: the changeset to commit 3832*2912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL 3833*2912Sartem * 3834*2912Sartem * Commit a changeset to the daemon. 3835*2912Sartem * 3836*2912Sartem * Returns: True if the changeset was committed on the daemon side 3837*2912Sartem */ 3838*2912Sartem dbus_bool_t 3839*2912Sartem libhal_device_commit_changeset (LibHalContext *ctx, LibHalChangeSet *changeset, DBusError *error) 3840*2912Sartem { 3841*2912Sartem LibHalChangeSetElement *elem; 3842*2912Sartem DBusMessage *message; 3843*2912Sartem DBusMessage *reply; 3844*2912Sartem DBusError _error; 3845*2912Sartem DBusMessageIter iter; 3846*2912Sartem DBusMessageIter sub; 3847*2912Sartem DBusMessageIter sub2; 3848*2912Sartem DBusMessageIter sub3; 3849*2912Sartem DBusMessageIter sub4; 3850*2912Sartem int i; 3851*2912Sartem 3852*2912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE); 3853*2912Sartem 3854*2912Sartem if (changeset->head == NULL) { 3855*2912Sartem return TRUE; 3856*2912Sartem } 3857*2912Sartem 3858*2912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", changeset->udi, 3859*2912Sartem "org.freedesktop.Hal.Device", 3860*2912Sartem "SetMultipleProperties"); 3861*2912Sartem 3862*2912Sartem if (message == NULL) { 3863*2912Sartem fprintf (stderr, "%s %d : Couldn't allocate D-BUS message\n", __FILE__, __LINE__); 3864*2912Sartem return FALSE; 3865*2912Sartem } 3866*2912Sartem 3867*2912Sartem dbus_message_iter_init_append (message, &iter); 3868*2912Sartem 3869*2912Sartem dbus_message_iter_open_container (&iter, 3870*2912Sartem DBUS_TYPE_ARRAY, 3871*2912Sartem DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING 3872*2912Sartem DBUS_TYPE_STRING_AS_STRING 3873*2912Sartem DBUS_TYPE_VARIANT_AS_STRING 3874*2912Sartem DBUS_DICT_ENTRY_END_CHAR_AS_STRING, 3875*2912Sartem &sub); 3876*2912Sartem 3877*2912Sartem for (elem = changeset->head; elem != NULL; elem = elem->next) { 3878*2912Sartem dbus_message_iter_open_container (&sub, 3879*2912Sartem DBUS_TYPE_DICT_ENTRY, 3880*2912Sartem NULL, 3881*2912Sartem &sub2); 3882*2912Sartem dbus_message_iter_append_basic (&sub2, DBUS_TYPE_STRING, &(elem->key)); 3883*2912Sartem 3884*2912Sartem switch (elem->change_type) { 3885*2912Sartem case LIBHAL_PROPERTY_TYPE_STRING: 3886*2912Sartem dbus_message_iter_open_container (&sub2, DBUS_TYPE_VARIANT, DBUS_TYPE_STRING_AS_STRING, &sub3); 3887*2912Sartem dbus_message_iter_append_basic (&sub3, DBUS_TYPE_STRING, &(elem->value.val_str)); 3888*2912Sartem dbus_message_iter_close_container (&sub2, &sub3); 3889*2912Sartem break; 3890*2912Sartem case LIBHAL_PROPERTY_TYPE_STRLIST: 3891*2912Sartem dbus_message_iter_open_container (&sub2, DBUS_TYPE_VARIANT, 3892*2912Sartem DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING, &sub3); 3893*2912Sartem dbus_message_iter_open_container (&sub3, DBUS_TYPE_ARRAY, 3894*2912Sartem DBUS_TYPE_STRING_AS_STRING, &sub4); 3895*2912Sartem for (i = 0; elem->value.val_strlist[i] != NULL; i++) { 3896*2912Sartem dbus_message_iter_append_basic (&sub4, DBUS_TYPE_STRING, 3897*2912Sartem &(elem->value.val_strlist[i])); 3898*2912Sartem } 3899*2912Sartem dbus_message_iter_close_container (&sub3, &sub4); 3900*2912Sartem dbus_message_iter_close_container (&sub2, &sub3); 3901*2912Sartem break; 3902*2912Sartem case LIBHAL_PROPERTY_TYPE_INT32: 3903*2912Sartem dbus_message_iter_open_container (&sub2, DBUS_TYPE_VARIANT, DBUS_TYPE_INT32_AS_STRING, &sub3); 3904*2912Sartem dbus_message_iter_append_basic (&sub3, DBUS_TYPE_INT32, &(elem->value.val_int)); 3905*2912Sartem dbus_message_iter_close_container (&sub2, &sub3); 3906*2912Sartem break; 3907*2912Sartem case LIBHAL_PROPERTY_TYPE_UINT64: 3908*2912Sartem dbus_message_iter_open_container (&sub2, DBUS_TYPE_VARIANT, DBUS_TYPE_UINT64_AS_STRING, &sub3); 3909*2912Sartem dbus_message_iter_append_basic (&sub3, DBUS_TYPE_UINT64, &(elem->value.val_uint64)); 3910*2912Sartem dbus_message_iter_close_container (&sub2, &sub3); 3911*2912Sartem break; 3912*2912Sartem case LIBHAL_PROPERTY_TYPE_DOUBLE: 3913*2912Sartem dbus_message_iter_open_container (&sub2, DBUS_TYPE_VARIANT, DBUS_TYPE_DOUBLE_AS_STRING, &sub3); 3914*2912Sartem dbus_message_iter_append_basic (&sub3, DBUS_TYPE_DOUBLE, &(elem->value.val_double)); 3915*2912Sartem dbus_message_iter_close_container (&sub2, &sub3); 3916*2912Sartem break; 3917*2912Sartem case LIBHAL_PROPERTY_TYPE_BOOLEAN: 3918*2912Sartem dbus_message_iter_open_container (&sub2, DBUS_TYPE_VARIANT, DBUS_TYPE_BOOLEAN_AS_STRING,&sub3); 3919*2912Sartem dbus_message_iter_append_basic (&sub3, DBUS_TYPE_BOOLEAN, &(elem->value.val_bool)); 3920*2912Sartem dbus_message_iter_close_container (&sub2, &sub3); 3921*2912Sartem break; 3922*2912Sartem default: 3923*2912Sartem fprintf (stderr, "%s %d : unknown change_type %d\n", __FILE__, __LINE__, elem->change_type); 3924*2912Sartem break; 3925*2912Sartem } 3926*2912Sartem dbus_message_iter_close_container (&sub, &sub2); 3927*2912Sartem } 3928*2912Sartem 3929*2912Sartem dbus_message_iter_close_container (&iter, &sub); 3930*2912Sartem 3931*2912Sartem 3932*2912Sartem dbus_error_init (&_error); 3933*2912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection, 3934*2912Sartem message, -1, 3935*2912Sartem &_error); 3936*2912Sartem 3937*2912Sartem dbus_move_error (&_error, error); 3938*2912Sartem if (error != NULL && dbus_error_is_set (error)) { 3939*2912Sartem fprintf (stderr, 3940*2912Sartem "%s %d : %s\n", 3941*2912Sartem __FILE__, __LINE__, error->message); 3942*2912Sartem 3943*2912Sartem dbus_message_unref (message); 3944*2912Sartem return FALSE; 3945*2912Sartem } 3946*2912Sartem 3947*2912Sartem if (reply == NULL) { 3948*2912Sartem dbus_message_unref (message); 3949*2912Sartem return FALSE; 3950*2912Sartem } 3951*2912Sartem 3952*2912Sartem return TRUE; 3953*2912Sartem } 3954*2912Sartem 3955*2912Sartem /** 3956*2912Sartem * libhal_device_free_changeset: 3957*2912Sartem * @changeset: the changeset to free 3958*2912Sartem * 3959*2912Sartem * Free a changeset. 3960*2912Sartem */ 3961*2912Sartem void 3962*2912Sartem libhal_device_free_changeset (LibHalChangeSet *changeset) 3963*2912Sartem { 3964*2912Sartem LibHalChangeSetElement *elem; 3965*2912Sartem LibHalChangeSetElement *elem2; 3966*2912Sartem 3967*2912Sartem for (elem = changeset->head; elem != NULL; elem = elem2) { 3968*2912Sartem elem2 = elem->next; 3969*2912Sartem 3970*2912Sartem switch (elem->change_type) { 3971*2912Sartem case LIBHAL_PROPERTY_TYPE_STRING: 3972*2912Sartem free (elem->value.val_str); 3973*2912Sartem break; 3974*2912Sartem case LIBHAL_PROPERTY_TYPE_STRLIST: 3975*2912Sartem libhal_free_string_array (elem->value.val_strlist); 3976*2912Sartem break; 3977*2912Sartem /* explicit fallthrough */ 3978*2912Sartem case LIBHAL_PROPERTY_TYPE_INT32: 3979*2912Sartem case LIBHAL_PROPERTY_TYPE_UINT64: 3980*2912Sartem case LIBHAL_PROPERTY_TYPE_DOUBLE: 3981*2912Sartem case LIBHAL_PROPERTY_TYPE_BOOLEAN: 3982*2912Sartem break; 3983*2912Sartem default: 3984*2912Sartem fprintf (stderr, "%s %d : unknown change_type %d\n", __FILE__, __LINE__, elem->change_type); 3985*2912Sartem break; 3986*2912Sartem } 3987*2912Sartem free (elem); 3988*2912Sartem } 3989*2912Sartem 3990*2912Sartem free (changeset->udi); 3991*2912Sartem free (changeset); 3992*2912Sartem } 3993