Main Page | Modules | Data Structures | File List | Data Fields | Related Pages

libhal.c

00001 /***************************************************************************
00002  * CVSID: $Id: libhal.c,v 1.17 2004/03/03 17:56:56 david Exp $
00003  *
00004  * libhal.c : HAL daemon C convenience library
00005  *
00006  * Copyright (C) 2003 David Zeuthen, <david@fubar.dk>
00007  *
00008  * Licensed under the Academic Free License version 2.0
00009  *
00010  * This program is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version.
00014  *
00015  * This program is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License
00021  * along with this program; if not, write to the Free Software
00022  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023  *
00024  **************************************************************************/
00025 
00026 #ifdef HAVE_CONFIG_H
00027 #  include <config.h>
00028 #endif
00029 
00030 #include <stdio.h>
00031 #include <stdlib.h>
00032 #include <string.h>
00033 #include <dbus/dbus.h>
00034 
00035 #include "libhal.h"
00036 
00049 void
00050 hal_free_string_array (char **str_array)
00051 {
00052     if (str_array != NULL) {
00053         int i;
00054 
00055         for (i = 0; str_array[i] != NULL; i++) {
00056             free (str_array[i]);
00057         }
00058         free (str_array);
00059     }
00060 }
00061 
00066 void
00067 hal_free_string (char *str)
00068 {
00070     free (str);
00071 }
00072 
00073 
00075 struct LibHalPropertySet_s {
00076     unsigned int num_properties; 
00077     LibHalProperty *properties_head;
00080 };
00081 
00083 struct LibHalProperty_s {
00084     int type;            
00085     char *key;           
00088     union {
00089         char *str_value;     
00090         dbus_int32_t int_value;
00092         double double_value; 
00093         dbus_bool_t bool_value;
00095     };
00096 
00097     LibHalProperty *next;        
00099 };
00100 
00101 static DBusConnection *connection;
00102 static dbus_bool_t is_initialized = FALSE;
00103 static dbus_bool_t cache_enabled = FALSE;
00104 static const LibHalFunctions *functions;
00105 
00112 LibHalPropertySet *
00113 hal_device_get_all_properties (const char *udi)
00114 {
00115     DBusError error;
00116     DBusMessage *message;
00117     DBusMessage *reply;
00118     DBusMessageIter iter;
00119     DBusMessageIter dict_iter;
00120     LibHalPropertySet *result;
00121     LibHalProperty **pn;
00122 
00123     message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
00124                         "org.freedesktop.Hal.Device",
00125                         "GetAllProperties");
00126     if (message == NULL) {
00127         fprintf (stderr,
00128              "%s %d : Couldn't allocate D-BUS message\n",
00129              __FILE__, __LINE__);
00130         return NULL;
00131     }
00132 
00133     dbus_error_init (&error);
00134     reply = dbus_connection_send_with_reply_and_block (connection,
00135                                message, -1,
00136                                &error);
00137     if (dbus_error_is_set (&error)) {
00138         fprintf (stderr, "%s %d: %s raised\n\"%s\"\n\n", __FILE__,
00139              __LINE__, error.name, error.message);
00140         dbus_message_unref (message);
00141         return NULL;
00142     }
00143 
00144     if (reply == NULL) {
00145         dbus_message_unref (message);
00146         return NULL;
00147     }
00148 
00149     dbus_message_iter_init (reply, &iter);
00150 
00151     result = malloc (sizeof (LibHalPropertySet));
00152     if (result == NULL) {
00153         fprintf (stderr, "%s %d : error allocating memory\n",
00154              __FILE__, __LINE__);
00155         dbus_message_unref (message);
00156         dbus_message_unref (reply);
00157         return NULL;
00158     }
00159 
00160 /*
00161     result->properties = malloc(sizeof(LibHalProperty)*result->num_properties);
00162     if( result->properties==NULL )
00163     {
00165     return NULL;
00166     }
00167 */
00168 
00169     pn = &result->properties_head;
00170     result->num_properties = 0;
00171 
00172     dbus_message_iter_init_dict_iterator (&iter, &dict_iter);
00173 
00174     do {
00175         char *dbus_str;
00176         LibHalProperty *p;
00177 
00178         p = malloc (sizeof (LibHalProperty));
00179         if (p == NULL) {
00180             fprintf (stderr,
00181                  "%s %d : error allocating memory\n",
00182                  __FILE__, __LINE__);
00184             return NULL;
00185         }
00186 
00187         *pn = p;
00188         pn = &p->next;
00189         p->next = NULL;
00190         result->num_properties++;
00191 
00192         dbus_str = dbus_message_iter_get_dict_key (&dict_iter);
00193         p->key =
00194             (char *) ((dbus_str != NULL) ? strdup (dbus_str) :
00195                   NULL);
00196         if (p->key == NULL) {
00197             fprintf (stderr,
00198                  "%s %d : error allocating memory\n",
00199                  __FILE__, __LINE__);
00201             return NULL;
00202         }
00203         dbus_free (dbus_str);
00204 
00205         p->type = dbus_message_iter_get_arg_type (&dict_iter);
00206 
00207         switch (p->type) {
00208         case DBUS_TYPE_STRING:
00209             dbus_str =
00210                 dbus_message_iter_get_string (&dict_iter);
00211             p->str_value =
00212                 (char *) ((dbus_str != NULL) ?
00213                       strdup (dbus_str) : NULL);
00214             if (p->str_value == NULL) {
00215                 fprintf (stderr,
00216                      "%s %d : error allocating memory\n",
00217                      __FILE__, __LINE__);
00219                 return NULL;
00220             }
00221             dbus_free (dbus_str);
00222             break;
00223         case DBUS_TYPE_INT32:
00224             p->int_value =
00225                 dbus_message_iter_get_int32 (&dict_iter);
00226             break;
00227         case DBUS_TYPE_DOUBLE:
00228             p->double_value =
00229                 dbus_message_iter_get_double (&dict_iter);
00230             break;
00231         case DBUS_TYPE_BOOLEAN:
00232             p->bool_value =
00233                 dbus_message_iter_get_boolean (&dict_iter);
00234             break;
00235 
00236         default:
00238             break;
00239         }
00240 
00241         dbus_message_iter_next (&dict_iter);
00242     }
00243     while (dbus_message_iter_has_next (&dict_iter));
00244 
00245     dbus_message_unref (message);
00246     dbus_message_unref (reply);
00247 
00248     return result;
00249 }
00250 
00255 void
00256 hal_free_property_set (LibHalPropertySet * set)
00257 {
00258     LibHalProperty *p;
00259     LibHalProperty *q;
00260 
00261     for (p = set->properties_head; p != NULL; p = q) {
00262         free (p->key);
00263         if (p->type == DBUS_TYPE_STRING)
00264             free (p->str_value);
00265         q = p->next;
00266         free (p);
00267     }
00268     free (set);
00269 }
00270 
00276 void
00277 hal_psi_init (LibHalPropertySetIterator * iter, LibHalPropertySet * set)
00278 {
00279     iter->set = set;
00280     iter->index = 0;
00281     iter->cur_prop = set->properties_head;
00282 }
00283 
00289 dbus_bool_t
00290 hal_psi_has_more (LibHalPropertySetIterator * iter)
00291 {
00292     return iter->index < iter->set->num_properties;
00293 }
00294 
00299 void
00300 hal_psi_next (LibHalPropertySetIterator * iter)
00301 {
00302     iter->index++;
00303     iter->cur_prop = iter->cur_prop->next;
00304 }
00305 
00312 int
00313 hal_psi_get_type (LibHalPropertySetIterator * iter)
00314 {
00315     return iter->cur_prop->type;
00316 }
00317 
00326 char *
00327 hal_psi_get_key (LibHalPropertySetIterator * iter)
00328 {
00329     return iter->cur_prop->key;
00330 }
00331 
00340 char *
00341 hal_psi_get_string (LibHalPropertySetIterator * iter)
00342 {
00343     return iter->cur_prop->str_value;
00344 }
00345 
00351 dbus_int32_t
00352 hal_psi_get_int (LibHalPropertySetIterator * iter)
00353 {
00354     return iter->cur_prop->int_value;
00355 }
00356 
00362 double
00363 hal_psi_get_double (LibHalPropertySetIterator * iter)
00364 {
00365     return iter->cur_prop->double_value;
00366 }
00367 
00373 dbus_bool_t
00374 hal_psi_get_bool (LibHalPropertySetIterator * iter)
00375 {
00376     return iter->cur_prop->bool_value;
00377 }
00378 
00379 
00380 static DBusHandlerResult
00381 filter_func (DBusConnection * connection,
00382          DBusMessage * message, void *user_data)
00383 {
00384     const char *object_path;
00385     DBusError error;
00386 
00387     dbus_error_init (&error);
00388 
00389     object_path = dbus_message_get_path (message);
00390 
00391     /*printf("*** in filter_func, object_path=%s\n", object_path); */
00392 
00393     if (dbus_message_is_signal (message, "org.freedesktop.Hal.Manager",
00394                     "DeviceAdded")) {
00395         char *udi;
00396         if (dbus_message_get_args (message, &error,
00397                        DBUS_TYPE_STRING, &udi,
00398                        DBUS_TYPE_INVALID)) {
00399             if (functions->device_added != NULL) {
00400                 functions->device_added (udi);
00401                 dbus_free (udi);
00402             }
00403         }
00404     } else
00405         if (dbus_message_is_signal
00406         (message, "org.freedesktop.Hal.Manager",
00407          "DeviceRemoved")) {
00408         char *udi;
00409         if (dbus_message_get_args (message, &error,
00410                        DBUS_TYPE_STRING, &udi,
00411                        DBUS_TYPE_INVALID)) {
00412             if (functions->device_removed != NULL) {
00413                 functions->device_removed (udi);
00414                 dbus_free (udi);
00415             }
00416         }
00417     } else
00418         if (dbus_message_is_signal
00419         (message, "org.freedesktop.Hal.Manager",
00420          "NewCapability")) {
00421         char *udi;
00422         char *capability;
00423         if (dbus_message_get_args (message, &error,
00424                        DBUS_TYPE_STRING, &udi,
00425                        DBUS_TYPE_STRING, &capability,
00426                        DBUS_TYPE_INVALID)) {
00427             if (functions->device_new_capability != NULL) {
00428                 functions->device_new_capability (udi,
00429                                   capability);
00430                 dbus_free (udi);
00431                 dbus_free (capability);
00432             }
00433         }
00434     } else
00435         if (dbus_message_is_signal
00436         (message, "org.freedesktop.Hal.Device", "Condition")) {
00437         if (functions->device_condition != NULL) {
00438             DBusMessageIter iter;
00439             char *condition_name;
00440 
00441             dbus_message_iter_init (message, &iter);
00442             condition_name =
00443                 dbus_message_iter_get_string (&iter);
00444 
00445             functions->device_condition (object_path,
00446                              condition_name,
00447                              message);
00448 
00449             dbus_free (condition_name);
00450         }
00451     } else
00452         if (dbus_message_is_signal
00453         (message, "org.freedesktop.Hal.Device",
00454          "PropertyModified")) {
00455         if (functions->device_property_modified != NULL) {
00456             int i;
00457             char *key;
00458             dbus_bool_t removed, added;
00459             int num_modifications;
00460             DBusMessageIter iter;
00461 
00462             dbus_message_iter_init (message, &iter);
00463             num_modifications =
00464                 dbus_message_iter_get_int32 (&iter);
00465             dbus_message_iter_next (&iter);
00466 
00467 
00468             for (i = 0; i < num_modifications; i++) {
00469 
00470                 key = dbus_message_iter_get_string (&iter);
00471                 dbus_message_iter_next (&iter);
00472                 removed =
00473                     dbus_message_iter_get_boolean (&iter);
00474                 dbus_message_iter_next (&iter);
00475                 added =
00476                     dbus_message_iter_get_boolean (&iter);
00477                 dbus_message_iter_next (&iter);
00478 
00479                 functions->
00480                     device_property_modified (object_path,
00481                                   key, removed,
00482                                   added);
00483 
00484                 dbus_free (key);
00485             }
00486 
00487         }
00488     }
00489 
00490     return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
00491 }
00492 
00493 static LibHalFunctions hal_null_functions = {
00494     NULL /*mainloop_integration */ ,
00495     NULL /*device_added */ ,
00496     NULL /*device_removed */ ,
00497     NULL /*device_new_capability */ ,
00498     NULL /*property_modified */ ,
00499     NULL /*device_condition */
00500 };
00501 
00520 int
00521 hal_initialize (const LibHalFunctions * cb_functions,
00522         dbus_bool_t use_cache)
00523 {
00524     DBusError error;
00525     
00526     if (is_initialized) {
00527         fprintf (stderr, "%s %d : Is already initialized!\n",
00528              __FILE__, __LINE__);
00529         return 1;
00530     }
00531 
00532     cache_enabled = use_cache;
00533 
00534     functions = cb_functions;
00535     /* allow caller to pass NULL */
00536     if (functions == NULL)
00537         functions = &hal_null_functions;
00538 
00539     /* connect to hald service on the system bus */
00540     dbus_error_init (&error);
00541     connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
00542     if (connection == NULL) {
00543         fprintf (stderr,
00544              "%s %d : Error connecting to system bus: %s\n",
00545              __FILE__, __LINE__, error.message);
00546         dbus_error_free (&error);
00547         return 1;
00548     }
00549 
00550     if (functions->main_loop_integration != NULL) {
00551 
00552         functions->main_loop_integration (connection);
00553     }
00554 
00555     if (!dbus_connection_add_filter
00556         (connection, filter_func, NULL, NULL)) {
00557         fprintf (stderr,
00558              "%s %d : Error creating connection handler\r\n",
00559              __FILE__, __LINE__);
00561         return 1;
00562     }
00563 
00564     dbus_bus_add_match (connection,
00565                 "type='signal',"
00566                 "interface='org.freedesktop.Hal.Manager',"
00567                 "sender='org.freedesktop.Hal',"
00568                 "path='/org/freedesktop/Hal/Manager'", &error);
00569     if (dbus_error_is_set (&error)) {
00570         fprintf (stderr, "%s %d : Error subscribing to signals, "
00571              "error=%s\r\n",
00572              __FILE__, __LINE__, error.message);
00574         return 1;
00575     }
00576 
00577     is_initialized = TRUE;
00578     return 0;
00579 }
00580 
00586 int
00587 hal_shutdown ()
00588 {
00589     if (!is_initialized)
00590         return 1;
00591 
00594     is_initialized = FALSE;
00595     return 0;
00596 }
00597 
00606 char **
00607 hal_get_all_devices (int *num_devices)
00608 {
00609     int i;
00610     DBusError error;
00611     DBusMessage *message;
00612     DBusMessage *reply;
00613     DBusMessageIter iter;
00614     char **device_names;
00615     char **hal_device_names;
00616 
00617     message = dbus_message_new_method_call ("org.freedesktop.Hal",
00618                         "/org/freedesktop/Hal/Manager",
00619                         "org.freedesktop.Hal.Manager",
00620                         "GetAllDevices");
00621     if (message == NULL) {
00622         fprintf (stderr,
00623              "%s %d : Couldn't allocate D-BUS message\n",
00624              __FILE__, __LINE__);
00625         return NULL;
00626     }
00627 
00628     dbus_error_init (&error);
00629     reply = dbus_connection_send_with_reply_and_block (connection,
00630                                message, -1,
00631                                &error);
00632     if (dbus_error_is_set (&error)) {
00633         fprintf (stderr, "%s %d : %s raised\n\"%s\"\n\n", __FILE__,
00634              __LINE__, error.name, error.message);
00635         dbus_message_unref (message);
00636         return NULL;
00637     }
00638 
00639     if (reply == NULL) {
00640         dbus_message_unref (message);
00641         return NULL;
00642     }
00643 
00644     /* now analyze reply */
00645     dbus_message_iter_init (reply, &iter);
00646     if (!dbus_message_iter_get_string_array (&iter,
00647                          &device_names,
00648                          num_devices)) {
00649         fprintf (stderr, "%s %d : wrong reply from hald\n",
00650              __FILE__, __LINE__);
00651         return NULL;
00652     }
00653 
00654     dbus_message_unref (reply);
00655     dbus_message_unref (message);
00656 
00657     /* Have to convert from dbus string array to hal string array 
00658      * since we can't poke at the dbus string array for the reason
00659      * that d-bus use their own memory allocation scheme
00660      */
00661     hal_device_names = malloc (sizeof (char *) * ((*num_devices) + 1));
00662     if (hal_device_names == NULL)
00663         return NULL;
00666     for (i = 0; i < (*num_devices); i++) {
00667         hal_device_names[i] = strdup (device_names[i]);
00668         if (hal_device_names[i] == NULL) {
00669             fprintf (stderr,
00670                  "%s %d : error allocating memory\n",
00671                  __FILE__, __LINE__);
00673             return NULL;
00674         }
00675     }
00676     hal_device_names[i] = NULL;
00677 
00678     dbus_free_string_array (device_names);
00679 
00680     return hal_device_names;
00681 }
00682 
00691 int
00692 hal_device_get_property_type (const char *udi, const char *key)
00693 {
00694     DBusError error;
00695     DBusMessage *message;
00696     DBusMessage *reply;
00697     DBusMessageIter iter;
00698     int type;
00699 
00700     message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
00701                         "org.freedesktop.Hal.Device",
00702                         "GetPropertyType");
00703     if (message == NULL) {
00704         fprintf (stderr,
00705              "%s %d : Couldn't allocate D-BUS message\n",
00706              __FILE__, __LINE__);
00707         return DBUS_TYPE_NIL;
00708     }
00709 
00710     dbus_message_iter_init (message, &iter);
00711     dbus_message_iter_append_string (&iter, key);
00712     dbus_error_init (&error);
00713     reply = dbus_connection_send_with_reply_and_block (connection,
00714                                message, -1,
00715                                &error);
00716     if (dbus_error_is_set (&error)) {
00717         fprintf (stderr, "%s %d : %s raised\n\"%s\"\n\n", __FILE__,
00718              __LINE__, error.name, error.message);
00719         dbus_message_unref (message);
00720         return DBUS_TYPE_NIL;
00721     }
00722     if (reply == NULL) {
00723         dbus_message_unref (message);
00724         return DBUS_TYPE_NIL;
00725     }
00726 
00727     dbus_message_iter_init (reply, &iter);
00728     type = dbus_message_iter_get_int32 (&iter);
00729 
00730     dbus_message_unref (message);
00731     dbus_message_unref (reply);
00732 
00733     return type;
00734 }
00735 
00746 char *
00747 hal_device_get_property_string (const char *udi, const char *key)
00748 {
00749     DBusError error;
00750     DBusMessage *message;
00751     DBusMessage *reply;
00752     DBusMessageIter iter;
00753     char *value;
00754     char *dbus_str;
00755 
00756     message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
00757                         "org.freedesktop.Hal.Device",
00758                         "GetPropertyString");
00759     if (message == NULL) {
00760         fprintf (stderr,
00761              "%s %d : Couldn't allocate D-BUS message\n",
00762              __FILE__, __LINE__);
00763         return NULL;
00764     }
00765 
00766     dbus_message_iter_init (message, &iter);
00767     dbus_message_iter_append_string (&iter, key);
00768     dbus_error_init (&error);
00769     reply = dbus_connection_send_with_reply_and_block (connection,
00770                                message, -1,
00771                                &error);
00772     if (dbus_error_is_set (&error)) {
00773         fprintf (stderr, "%s %d : Error sending msg: %s\n",
00774              __FILE__, __LINE__, error.message);
00775         dbus_message_unref (message);
00776         return NULL;
00777     }
00778     if (reply == NULL) {
00779         dbus_message_unref (message);
00780         return NULL;
00781     }
00782 
00783     dbus_message_iter_init (reply, &iter);
00784 
00785     /* now analyze reply */
00786     if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_NIL) {
00787         fprintf (stderr,
00788              "%s %d : property '%s' for device '%s' does not "
00789              "exist\n", __FILE__, __LINE__, key, udi);
00790         dbus_message_unref (message);
00791         dbus_message_unref (reply);
00792         return NULL;
00793     } else if (dbus_message_iter_get_arg_type (&iter) !=
00794            DBUS_TYPE_STRING) {
00795         fprintf (stderr,
00796              "%s %d : property '%s' for device '%s' is not "
00797              "of type string\n", __FILE__, __LINE__, key, udi);
00798         dbus_message_unref (message);
00799         dbus_message_unref (reply);
00800         return NULL;
00801     }
00802 
00803     dbus_str = dbus_message_iter_get_string (&iter);
00804     value = (char *) ((dbus_str != NULL) ? strdup (dbus_str) : NULL);
00805     if (value == NULL) {
00806         fprintf (stderr, "%s %d : error allocating memory\n",
00807              __FILE__, __LINE__);
00809         return NULL;
00810     }
00811     dbus_free (dbus_str);
00812 
00813     dbus_message_unref (message);
00814     dbus_message_unref (reply);
00815     return value;
00816 }
00817 
00824 dbus_int32_t
00825 hal_device_get_property_int (const char *udi, const char *key)
00826 {
00827     DBusError error;
00828     DBusMessage *message;
00829     DBusMessage *reply;
00830     DBusMessageIter iter;
00831     dbus_int32_t value;
00832 
00833     message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
00834                         "org.freedesktop.Hal.Device",
00835                         "GetPropertyInteger");
00836     if (message == NULL) {
00837         fprintf (stderr,
00838              "%s %d : Couldn't allocate D-BUS message\n",
00839              __FILE__, __LINE__);
00840         return -1;
00841     }
00842 
00843     dbus_message_iter_init (message, &iter);
00844     dbus_message_iter_append_string (&iter, key);
00845     dbus_error_init (&error);
00846     reply = dbus_connection_send_with_reply_and_block (connection,
00847                                message, -1,
00848                                &error);
00849     if (dbus_error_is_set (&error)) {
00850         fprintf (stderr, "%s %d : Error sending msg: %s\n",
00851              __FILE__, __LINE__, error.message);
00852         dbus_message_unref (message);
00853         return -1;
00854     }
00855     if (reply == NULL) {
00856         dbus_message_unref (message);
00857         return -1;
00858     }
00859 
00860     dbus_message_iter_init (reply, &iter);
00861 
00862     /* now analyze reply */
00863     if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_NIL) {
00864         /* property didn't exist */
00865         fprintf (stderr,
00866              "%s %d : property '%s' for device '%s' does not "
00867              "exist\n", __FILE__, __LINE__, key, udi);
00868         dbus_message_unref (message);
00869         dbus_message_unref (reply);
00870         return -1;
00871     } else if (dbus_message_iter_get_arg_type (&iter) !=
00872            DBUS_TYPE_INT32) {
00873         fprintf (stderr,
00874              "%s %d : property '%s' for device '%s' is not "
00875              "of type integer\n", __FILE__, __LINE__, key,
00876              udi);
00877         dbus_message_unref (message);
00878         dbus_message_unref (reply);
00879         return -1;
00880     }
00881     value = dbus_message_iter_get_int32 (&iter);
00882 
00883     dbus_message_unref (message);
00884     dbus_message_unref (reply);
00885     return value;
00886 }
00887 
00894 double
00895 hal_device_get_property_double (const char *udi, const char *key)
00896 {
00897     DBusError error;
00898     DBusMessage *message;
00899     DBusMessage *reply;
00900     DBusMessageIter iter;
00901     double value;
00902 
00903     message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
00904                         "org.freedesktop.Hal.Device",
00905                         "GetPropertyDouble");
00906     if (message == NULL) {
00907         fprintf (stderr,
00908              "%s %d : Couldn't allocate D-BUS message\n",
00909              __FILE__, __LINE__);
00910         return -1.0f;
00911     }
00912 
00913     dbus_message_iter_init (message, &iter);
00914     dbus_message_iter_append_string (&iter, key);
00915     dbus_error_init (&error);
00916     reply = dbus_connection_send_with_reply_and_block (connection,
00917                                message, -1,
00918                                &error);
00919     if (dbus_error_is_set (&error)) {
00920         fprintf (stderr, "%s %d : Error sending msg: %s\n",
00921              __FILE__, __LINE__, error.message);
00922         dbus_message_unref (message);
00923         return -1.0f;
00924     }
00925     if (reply == NULL) {
00926         dbus_message_unref (message);
00927         return -1.0f;
00928     }
00929 
00930     dbus_message_iter_init (reply, &iter);
00931 
00932     /* now analyze reply */
00933     if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_NIL) {
00934         /* property didn't exist */
00935         fprintf (stderr,
00936              "%s %d : property '%s' for device '%s' does not "
00937              "exist\n", __FILE__, __LINE__, key, udi);
00938         dbus_message_unref (message);
00939         dbus_message_unref (reply);
00940         return -1.0f;
00941     } else if (dbus_message_iter_get_arg_type (&iter) !=
00942            DBUS_TYPE_DOUBLE) {
00943         fprintf (stderr,
00944              "%s %d : property '%s' for device '%s' is not "
00945              "of type double\n", __FILE__, __LINE__, key, udi);
00946         dbus_message_unref (message);
00947         dbus_message_unref (reply);
00948         return -1.0f;
00949     }
00950     value = dbus_message_iter_get_double (&iter);
00951 
00952     dbus_message_unref (message);
00953     dbus_message_unref (reply);
00954     return (double) value;
00955 }
00956 
00963 dbus_bool_t
00964 hal_device_get_property_bool (const char *udi, const char *key)
00965 {
00966     DBusError error;
00967     DBusMessage *message;
00968     DBusMessage *reply;
00969     DBusMessageIter iter;
00970     double value;
00971 
00972     message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
00973                         "org.freedesktop.Hal.Device",
00974                         "GetPropertyBoolean");
00975     if (message == NULL) {
00976         fprintf (stderr,
00977              "%s %d : Couldn't allocate D-BUS message\n",
00978              __FILE__, __LINE__);
00979         return FALSE;
00980     }
00981 
00982     dbus_message_iter_init (message, &iter);
00983     dbus_message_iter_append_string (&iter, key);
00984     dbus_error_init (&error);
00985     reply = dbus_connection_send_with_reply_and_block (connection,
00986                                message, -1,
00987                                &error);
00988     if (dbus_error_is_set (&error)) {
00989         fprintf (stderr, "%s %d : Error sending msg: %s\n",
00990              __FILE__, __LINE__, error.message);
00991         dbus_message_unref (message);
00992         return FALSE;
00993     }
00994     if (reply == NULL) {
00995         dbus_message_unref (message);
00996         return FALSE;
00997     }
00998 
00999     dbus_message_iter_init (reply, &iter);
01000 
01001     /* now analyze reply */
01002     if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_NIL) {
01003         /* property didn't exist */
01004         fprintf (stderr,
01005              "%s %d : property '%s' for device '%s' does not "
01006              "exist\n", __FILE__, __LINE__, key, udi);
01007         dbus_message_unref (message);
01008         dbus_message_unref (reply);
01009         return FALSE;
01010     } else if (dbus_message_iter_get_arg_type (&iter) !=
01011            DBUS_TYPE_BOOLEAN) {
01012         fprintf (stderr,
01013              "%s %d : property '%s' for device '%s' is not "
01014              "of type bool\n", __FILE__, __LINE__, key, udi);
01015         dbus_message_unref (message);
01016         dbus_message_unref (reply);
01017         return FALSE;
01018     }
01019     value = dbus_message_iter_get_boolean (&iter);
01020 
01021     dbus_message_unref (message);
01022     dbus_message_unref (reply);
01023     return value;
01024 }
01025 
01026 
01027 /* generic helper */
01028 static int
01029 hal_device_set_property_helper (const char *udi,
01030                 const char *key,
01031                 int type,
01032                 const char *str_value,
01033                 dbus_int32_t int_value,
01034                 double double_value,
01035                 dbus_bool_t bool_value)
01036 {
01037     DBusError error;
01038     DBusMessage *message;
01039     DBusMessage *reply;
01040     DBusMessageIter iter;
01041     char *method_name = NULL;
01042 
01045     switch (type) {
01046     case DBUS_TYPE_NIL:
01047         method_name = "RemoveProperty";
01048         break;
01049     case DBUS_TYPE_STRING:
01050         method_name = "SetPropertyString";
01051         break;
01052     case DBUS_TYPE_INT32:
01053         method_name = "SetPropertyInteger";
01054         break;
01055     case DBUS_TYPE_DOUBLE:
01056         method_name = "SetPropertyDouble";
01057         break;
01058     case DBUS_TYPE_BOOLEAN:
01059         method_name = "SetPropertyBoolean";
01060         break;
01061 
01062     default:
01063         /* cannot happen; is not callable from outside this file */
01064         break;
01065     }
01066 
01067     message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
01068                         "org.freedesktop.Hal.Device",
01069                         method_name);
01070     if (message == NULL) {
01071         fprintf (stderr,
01072              "%s %d : Couldn't allocate D-BUS message\n",
01073              __FILE__, __LINE__);
01074         return FALSE;
01075     }
01076 
01077     dbus_message_iter_init (message, &iter);
01078     dbus_message_iter_append_string (&iter, key);
01079     switch (type) {
01080     case DBUS_TYPE_NIL:
01081         dbus_message_iter_append_nil (&iter);
01082         break;
01083     case DBUS_TYPE_STRING:
01084         dbus_message_iter_append_string (&iter, str_value);
01085         break;
01086     case DBUS_TYPE_INT32:
01087         dbus_message_iter_append_int32 (&iter, int_value);
01088         break;
01089     case DBUS_TYPE_DOUBLE:
01090         dbus_message_iter_append_double (&iter, double_value);
01091         break;
01092     case DBUS_TYPE_BOOLEAN:
01093         dbus_message_iter_append_boolean (&iter, bool_value);
01094         break;
01095     }
01096 
01097     dbus_error_init (&error);
01098     reply = dbus_connection_send_with_reply_and_block (connection,
01099                                message, -1,
01100                                &error);
01101     if (dbus_error_is_set (&error)) {
01102         fprintf (stderr, "%s %d: %s raised\n\"%s\"\n\n", __FILE__,
01103              __LINE__, error.name, error.message);
01104         dbus_message_unref (message);
01105         return FALSE;
01106     }
01107 
01108     if (reply == NULL) {
01109         dbus_message_unref (message);
01110         return FALSE;
01111     }
01112 
01113     return TRUE;
01114 }
01115 
01125 dbus_bool_t
01126 hal_device_set_property_string (const char *udi,
01127                 const char *key, const char *value)
01128 {
01129     return hal_device_set_property_helper (udi, key,
01130                            DBUS_TYPE_STRING,
01131                            value, 0, 0.0f, FALSE);
01132 }
01133 
01143 dbus_bool_t
01144 hal_device_set_property_int (const char *udi,
01145                  const char *key, dbus_int32_t value)
01146 {
01147     return hal_device_set_property_helper (udi, key,
01148                            DBUS_TYPE_INT32,
01149                            NULL, value, 0.0f, FALSE);
01150 }
01151 
01161 dbus_bool_t
01162 hal_device_set_property_double (const char *udi,
01163                 const char *key, double value)
01164 {
01165     return hal_device_set_property_helper (udi, key,
01166                            DBUS_TYPE_DOUBLE,
01167                            NULL, 0, value, FALSE);
01168 }
01169 
01179 dbus_bool_t
01180 hal_device_set_property_bool (const char *udi,
01181                   const char *key, dbus_bool_t value)
01182 {
01183     return hal_device_set_property_helper (udi, key,
01184                            DBUS_TYPE_BOOLEAN,
01185                            NULL, 0, 0.0f, value);
01186 }
01187 
01188 
01196 dbus_bool_t
01197 hal_device_remove_property (const char *udi, const char *key)
01198 {
01199     return hal_device_set_property_helper (udi, key, DBUS_TYPE_NIL, 
01200                            /* DBUS_TYPE_NIL means remove */
01201                            NULL, 0, 0.0f, FALSE);
01202 }
01203 
01204 
01215 char *
01216 hal_agent_new_device ()
01217 {
01218     DBusError error;
01219     DBusMessage *message;
01220     DBusMessage *reply;
01221     DBusMessageIter iter;
01222     char *value;
01223     char *dbus_str;
01224 
01225     message = dbus_message_new_method_call ("org.freedesktop.Hal",
01226                         "/org/freedesktop/Hal/Manager",
01227                         "org.freedesktop.Hal.AgentManager",
01228                         "NewDevice");
01229     if (message == NULL) {
01230         fprintf (stderr,
01231              "%s %d : Couldn't allocate D-BUS message\n",
01232              __FILE__, __LINE__);
01233         return NULL;
01234     }
01235 
01236     dbus_error_init (&error);
01237     reply = dbus_connection_send_with_reply_and_block (connection,
01238                                message, -1,
01239                                &error);
01240     if (dbus_error_is_set (&error)) {
01241         fprintf (stderr, "%s %d : Error sending msg: %s\n",
01242              __FILE__, __LINE__, error.message);
01243         dbus_message_unref (message);
01244         return NULL;
01245     }
01246     if (reply == NULL) {
01247         dbus_message_unref (message);
01248         return NULL;
01249     }
01250 
01251     dbus_message_iter_init (reply, &iter);
01252 
01253     /* now analyze reply */
01254     if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING) {
01255         fprintf (stderr,
01256              "%s %d : expected a string in reply to NewDevice\n",
01257              __FILE__, __LINE__);
01258         dbus_message_unref (message);
01259         dbus_message_unref (reply);
01260         return NULL;
01261     }
01262 
01263     dbus_str = dbus_message_iter_get_string (&iter);
01264     value = (char *) ((dbus_str != NULL) ? strdup (dbus_str) : NULL);
01265     if (value == NULL) {
01266         fprintf (stderr, "%s %d : error allocating memory\n",
01267              __FILE__, __LINE__);
01269         return NULL;
01270     }
01271     dbus_free (dbus_str);
01272 
01273     dbus_message_unref (message);
01274     dbus_message_unref (reply);
01275     return value;
01276 }
01277 
01278 
01296 dbus_bool_t
01297 hal_agent_commit_to_gdl (const char *temp_udi, const char *udi)
01298 {
01299     DBusError error;
01300     DBusMessage *message;
01301     DBusMessage *reply;
01302     DBusMessageIter iter;
01303 
01304     message = dbus_message_new_method_call ("org.freedesktop.Hal",
01305                         "/org/freedesktop/Hal/Manager",
01306                         "org.freedesktop.Hal.AgentManager",
01307                         "CommitToGdl");
01308     if (message == NULL) {
01309         fprintf (stderr,
01310              "%s %d : Couldn't allocate D-BUS message\n",
01311              __FILE__, __LINE__);
01312         return FALSE;
01313     }
01314 
01315     dbus_message_iter_init (message, &iter);
01316     dbus_message_iter_append_string (&iter, temp_udi);
01317     dbus_message_iter_append_string (&iter, udi);
01318 
01319     dbus_error_init (&error);
01320     reply = dbus_connection_send_with_reply_and_block (connection,
01321                                message, -1,
01322                                &error);
01323     if (dbus_error_is_set (&error)) {
01324         if (dbus_error_has_name
01325             (&error, "org.freedesktop.Hal.UdiInUse"))
01326             return FALSE;
01327         fprintf (stderr, "%s %d : Error sending msg: %s\n",
01328              __FILE__, __LINE__, error.message);
01329         dbus_message_unref (message);
01330         return FALSE;
01331     }
01332     if (reply == NULL) {
01333         dbus_message_unref (message);
01334         return FALSE;
01335     }
01336 
01337     dbus_message_unref (message);
01338     dbus_message_unref (reply);
01339     return TRUE;
01340 }
01341 
01352 dbus_bool_t
01353 hal_agent_remove_device (const char *udi)
01354 {
01355     DBusError error;
01356     DBusMessage *message;
01357     DBusMessage *reply;
01358     DBusMessageIter iter;
01359 
01360     message = dbus_message_new_method_call ("org.freedesktop.Hal",
01361                         "/org/freedesktop/Hal/Manager",
01362                         "org.freedesktop.Hal.AgentManager",
01363                         "Remove");
01364     if (message == NULL) {
01365         fprintf (stderr,
01366              "%s %d : Couldn't allocate D-BUS message\n",
01367              __FILE__, __LINE__);
01368         return FALSE;
01369     }
01370 
01371     dbus_message_iter_init (message, &iter);
01372     dbus_message_iter_append_string (&iter, udi);
01373 
01374     dbus_error_init (&error);
01375     reply = dbus_connection_send_with_reply_and_block (connection,
01376                                message, -1,
01377                                &error);
01378     if (dbus_error_is_set (&error)) {
01379         fprintf (stderr, "%s %d : Error sending msg: %s\n",
01380              __FILE__, __LINE__, error.message);
01381         dbus_message_unref (message);
01382         return FALSE;
01383     }
01384     if (reply == NULL) {
01385         dbus_message_unref (message);
01386         return FALSE;
01387     }
01388 
01389     dbus_message_unref (message);
01390     dbus_message_unref (reply);
01391     return TRUE;
01392 }
01393 
01399 dbus_bool_t
01400 hal_device_exists (const char *udi)
01401 {
01402     DBusError error;
01403     DBusMessage *message;
01404     DBusMessage *reply;
01405     DBusMessageIter iter;
01406     dbus_bool_t value;
01407 
01408     message = dbus_message_new_method_call ("org.freedesktop.Hal",
01409                         "/org/freedesktop/Hal/Manager",
01410                         "org.freedesktop.Hal.Manager",
01411                         "DeviceExists");
01412     if (message == NULL) {
01413         fprintf (stderr,
01414              "%s %d : Couldn't allocate D-BUS message\n",
01415              __FILE__, __LINE__);
01416         return FALSE;
01417     }
01418 
01419     dbus_message_iter_init (message, &iter);
01420     dbus_message_iter_append_string (&iter, udi);
01421 
01422     dbus_error_init (&error);
01423     reply = dbus_connection_send_with_reply_and_block (connection,
01424                                message, -1,
01425                                &error);
01426     if (dbus_error_is_set (&error)) {
01427         fprintf (stderr, "%s %d : Error sending msg: %s\n",
01428              __FILE__, __LINE__, error.message);
01429         dbus_message_unref (message);
01430         return FALSE;
01431     }
01432     if (reply == NULL) {
01433         dbus_message_unref (message);
01434         return FALSE;
01435     }
01436 
01437     dbus_message_iter_init (reply, &iter);
01438 
01439     /* now analyze reply */
01440     if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_BOOLEAN) {
01441         fprintf (stderr,
01442              "%s %d : expected a bool in reply to DeviceExists\n",
01443              __FILE__, __LINE__);
01444         dbus_message_unref (message);
01445         dbus_message_unref (reply);
01446         return FALSE;
01447     }
01448 
01449     value = dbus_message_iter_get_boolean (&iter);
01450 
01451     dbus_message_unref (message);
01452     dbus_message_unref (reply);
01453     return value;
01454 }
01455 
01462 dbus_bool_t
01463 hal_device_property_exists (const char *udi, const char *key)
01464 {
01465     DBusError error;
01466     DBusMessage *message;
01467     DBusMessage *reply;
01468     DBusMessageIter iter;
01469     dbus_bool_t value;
01470 
01471     message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
01472                         "org.freedesktop.Hal.Device",
01473                         "PropertyExists");
01474     if (message == NULL) {
01475         fprintf (stderr,
01476              "%s %d : Couldn't allocate D-BUS message\n",
01477              __FILE__, __LINE__);
01478         return FALSE;
01479     }
01480 
01481     dbus_message_iter_init (message, &iter);
01482     dbus_message_iter_append_string (&iter, key);
01483 
01484     dbus_error_init (&error);
01485     reply = dbus_connection_send_with_reply_and_block (connection,
01486                                message, -1,
01487                                &error);
01488     if (dbus_error_is_set (&error)) {
01489         fprintf (stderr, "%s %d : Error sending msg: %s\n",
01490              __FILE__, __LINE__, error.message);
01491         dbus_message_unref (message);
01492         return FALSE;
01493     }
01494     if (reply == NULL) {
01495         dbus_message_unref (message);
01496         return FALSE;
01497     }
01498 
01499     dbus_message_iter_init (reply, &iter);
01500 
01501     /* now analyse reply */
01502     if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_BOOLEAN) {
01503         fprintf (stderr, "%s %d : expected a bool in reply to "
01504              "PropertyExists\n", __FILE__, __LINE__);
01505         dbus_message_unref (message);
01506         dbus_message_unref (reply);
01507         return FALSE;
01508     }
01509 
01510     value = dbus_message_iter_get_boolean (&iter);
01511 
01512     dbus_message_unref (message);
01513     dbus_message_unref (reply);
01514     return value;
01515 }
01516 
01523 dbus_bool_t
01524 hal_agent_merge_properties (const char *target_udi, const char *source_udi)
01525 {
01526     DBusError error;
01527     DBusMessage *message;
01528     DBusMessage *reply;
01529     DBusMessageIter iter;
01530 
01531     message = dbus_message_new_method_call ("org.freedesktop.Hal",
01532                         "/org/freedesktop/Hal/Manager",
01533                         "org.freedesktop.Hal.AgentManager",
01534                         "MergeProperties");
01535     if (message == NULL) {
01536         fprintf (stderr,
01537              "%s %d : Couldn't allocate D-BUS message\n",
01538              __FILE__, __LINE__);
01539         return FALSE;
01540     }
01541 
01542     dbus_message_iter_init (message, &iter);
01543     dbus_message_iter_append_string (&iter, target_udi);
01544     dbus_message_iter_append_string (&iter, source_udi);
01545 
01546     dbus_error_init (&error);
01547     reply = dbus_connection_send_with_reply_and_block (connection,
01548                                message, -1,
01549                                &error);
01550     if (dbus_error_is_set (&error)) {
01551         if (dbus_error_has_name
01552             (&error, "org.freedesktop.Hal.NoSuchDevice"))
01553             return FALSE;
01554         fprintf (stderr, "%s %d : Error sending msg: %s\n",
01555              __FILE__, __LINE__, error.message);
01556         dbus_message_unref (message);
01557         return FALSE;
01558     }
01559     if (reply == NULL) {
01560         dbus_message_unref (message);
01561         return FALSE;
01562     }
01563 
01564     dbus_message_unref (message);
01565     dbus_message_unref (reply);
01566     return TRUE;
01567 }
01568 
01587 dbus_bool_t
01588 hal_agent_device_matches (const char *udi1, const char *udi2,
01589               const char *namespace)
01590 {
01591     DBusError error;
01592     DBusMessage *message;
01593     DBusMessage *reply;
01594     DBusMessageIter iter;
01595     dbus_bool_t value;
01596 
01597     message = dbus_message_new_method_call ("org.freedesktop.Hal",
01598                         "/org/freedesktop/Hal/Manager",
01599                         "org.freedesktop.Hal.AgentManager",
01600                         "DeviceMatches");
01601     if (message == NULL) {
01602         fprintf (stderr,
01603              "%s %d : Couldn't allocate D-BUS message\n",
01604              __FILE__, __LINE__);
01605         return FALSE;
01606     }
01607 
01608     dbus_message_iter_init (message, &iter);
01609     dbus_message_iter_append_string (&iter, udi1);
01610     dbus_message_iter_append_string (&iter, udi2);
01611     dbus_message_iter_append_string (&iter, namespace);
01612 
01613     dbus_error_init (&error);
01614     reply = dbus_connection_send_with_reply_and_block (connection,
01615                                message, -1,
01616                                &error);
01617     if (dbus_error_is_set (&error)) {
01618         fprintf (stderr, "%s %d : Error sending msg: %s\n",
01619              __FILE__, __LINE__, error.message);
01620         dbus_message_unref (message);
01621         return FALSE;
01622     }
01623     if (reply == NULL) {
01624         dbus_message_unref (message);
01625         return FALSE;
01626     }
01627     /* now analyse reply */
01628     dbus_message_iter_init (reply, &iter);
01629     if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_BOOLEAN) {
01630         fprintf (stderr,
01631              "%s %d : expected a bool in reply to DeviceMatches\n",
01632              __FILE__, __LINE__);
01633         dbus_message_unref (message);
01634         dbus_message_unref (reply);
01635         return FALSE;
01636     }
01637 
01638     value = dbus_message_iter_get_boolean (&iter);
01639 
01640     dbus_message_unref (message);
01641     dbus_message_unref (reply);
01642     return value;
01643 }
01644 
01649 void
01650 hal_device_print (const char *udi)
01651 {
01652     int type;
01653     char *key;
01654     LibHalPropertySet *pset;
01655     LibHalPropertySetIterator i;
01656 
01657     printf ("device_id = %s\n", udi);
01658 
01659     pset = hal_device_get_all_properties (udi);
01660 
01661     for (hal_psi_init (&i, pset); hal_psi_has_more (&i);
01662          hal_psi_next (&i)) {
01663         type = hal_psi_get_type (&i);
01664         key = hal_psi_get_key (&i);
01665         switch (type) {
01666         case DBUS_TYPE_STRING:
01667             printf ("    %s = %s (string)\n", key,
01668                 hal_psi_get_string (&i));
01669             break;
01670         case DBUS_TYPE_INT32:
01671             printf ("    %s = %d = 0x%x (int)\n", key,
01672                 hal_psi_get_int (&i),
01673                 hal_psi_get_int (&i));
01674             break;
01675         case DBUS_TYPE_BOOLEAN:
01676             printf ("    %s = %s (bool)\n", key,
01677                 (hal_psi_get_bool (&i) ? "true" :
01678                  "false"));
01679             break;
01680         case DBUS_TYPE_DOUBLE:
01681             printf ("    %s = %g (double)\n", key,
01682                 hal_psi_get_double (&i));
01683             break;
01684         default:
01685             printf ("    *** unknown type for key %s\n", key);
01686             break;
01687         }
01688     }
01689     hal_free_property_set (pset);
01690 }
01691 
01701 char **
01702 hal_manager_find_device_string_match (const char *key,
01703                       const char *value, int *num_devices)
01704 {
01705     int i;
01706     DBusError error;
01707     DBusMessage *message;
01708     DBusMessage *reply;
01709     DBusMessageIter iter;
01710     char **device_names;
01711     char **hal_device_names;
01712 
01713     message = dbus_message_new_method_call ("org.freedesktop.Hal",
01714                         "/org/freedesktop/Hal/Manager",
01715                         "org.freedesktop.Hal.Manager",
01716                         "FindDeviceStringMatch");
01717     if (message == NULL) {
01718         fprintf (stderr,
01719              "%s %d : Couldn't allocate D-BUS message\n",
01720              __FILE__, __LINE__);
01721         return NULL;
01722     }
01723 
01724     dbus_message_iter_init (message, &iter);
01725     dbus_message_iter_append_string (&iter, key);
01726     dbus_message_iter_append_string (&iter, value);
01727 
01728     dbus_error_init (&error);
01729     reply = dbus_connection_send_with_reply_and_block (connection,
01730                                message, -1,
01731                                &error);
01732     if (dbus_error_is_set (&error)) {
01733         fprintf (stderr, "%s %d : Error sending msg: %s\n",
01734              __FILE__, __LINE__, error.message);
01735         dbus_message_unref (message);
01736         return NULL;
01737     }
01738     if (reply == NULL) {
01739         dbus_message_unref (message);
01740         return NULL;
01741     }
01742     /* now analyse reply */
01743     dbus_message_iter_init (reply, &iter);
01744     if (!dbus_message_iter_get_string_array (&iter,
01745                          &device_names,
01746                          num_devices)) {
01747         fprintf (stderr, "%s %d : wrong reply from hald\n",
01748              __FILE__, __LINE__);
01749         return NULL;
01750     }
01751 
01752     dbus_message_unref (message);
01753     dbus_message_unref (reply);
01754 
01755     /* Have to convert from dbus string array to hal string array 
01756      * since we can't poke at the dbus string array for the reason
01757      * that d-bus use their own memory allocation scheme
01758      */
01759     hal_device_names = malloc (sizeof (char *) * ((*num_devices) + 1));
01760     if (hal_device_names == NULL)
01761         return NULL;
01764     for (i = 0; i < (*num_devices); i++) {
01765         hal_device_names[i] = strdup (device_names[i]);
01766         if (hal_device_names[i] == NULL)
01767             return NULL;
01769     }
01770     hal_device_names[i] = NULL;
01771 
01772     dbus_free_string_array (device_names);
01773 
01774     return hal_device_names;
01775 }
01776 
01777 
01785 dbus_bool_t
01786 hal_device_add_capability (const char *udi, const char *capability)
01787 {
01788     DBusError error;
01789     DBusMessage *message;
01790     DBusMessage *reply;
01791     DBusMessageIter iter;
01792 
01793     message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
01794                         "org.freedesktop.Hal.Device",
01795                         "AddCapability");
01796     if (message == NULL) {
01797         fprintf (stderr,
01798              "%s %d : Couldn't allocate D-BUS message\n",
01799              __FILE__, __LINE__);
01800         return FALSE;
01801     }
01802 
01803     dbus_message_iter_init (message, &iter);
01804     dbus_message_iter_append_string (&iter, capability);
01805 
01806     dbus_error_init (&error);
01807     reply = dbus_connection_send_with_reply_and_block (connection,
01808                                message, -1,
01809                                &error);
01810     if (dbus_error_is_set (&error)) {
01811         fprintf (stderr, "%s %d: %s raised\n\"%s\"\n\n", __FILE__,
01812              __LINE__, error.name, error.message);
01813         dbus_message_unref (message);
01814         return FALSE;
01815     }
01816 
01817     if (reply == NULL) {
01818         dbus_message_unref (message);
01819         return FALSE;
01820     }
01821 
01822     dbus_message_unref (reply);
01823     dbus_message_unref (message);
01824     return TRUE;
01825 }
01826 
01835 dbus_bool_t
01836 hal_device_query_capability (const char *udi, const char *capability)
01837 {
01838     char *caps;
01839 
01840     caps = hal_device_get_property_string (udi, "info.capabilities");
01841 
01842     if (caps != NULL)
01843         if (strstr (caps, capability) != NULL)
01844             return TRUE;
01845 
01846     return FALSE;
01847 }
01848 
01856 char **
01857 hal_find_device_by_capability (const char *capability, int *num_devices)
01858 {
01859     int i;
01860     DBusError error;
01861     DBusMessage *message;
01862     DBusMessage *reply;
01863     DBusMessageIter iter;
01864     char **device_names;
01865     char **hal_device_names;
01866 
01867     message = dbus_message_new_method_call ("org.freedesktop.Hal",
01868                         "/org/freedesktop/Hal/Manager",
01869                         "org.freedesktop.Hal.Manager",
01870                         "FindDeviceByCapability");
01871     if (message == NULL) {
01872         fprintf (stderr,
01873              "%s %d : Couldn't allocate D-BUS message\n",
01874              __FILE__, __LINE__);
01875         return NULL;
01876     }
01877 
01878     dbus_message_iter_init (message, &iter);
01879     dbus_message_iter_append_string (&iter, capability);
01880 
01881     dbus_error_init (&error);
01882     reply = dbus_connection_send_with_reply_and_block (connection,
01883                                message, -1,
01884                                &error);
01885     if (dbus_error_is_set (&error)) {
01886         fprintf (stderr, "%s %d : Error sending msg: %s\n",
01887              __FILE__, __LINE__, error.message);
01888         dbus_message_unref (message);
01889         return NULL;
01890     }
01891     if (reply == NULL) {
01892         dbus_message_unref (message);
01893         return NULL;
01894     }
01895     /* now analyse reply */
01896     dbus_message_iter_init (reply, &iter);
01897     if (!dbus_message_iter_get_string_array (&iter,
01898                          &device_names,
01899                          num_devices)) {
01900         fprintf (stderr, "%s %d : wrong reply from hald\n",
01901              __FILE__, __LINE__);
01902         return NULL;
01903     }
01904 
01905     dbus_message_unref (message);
01906     dbus_message_unref (reply);
01907 
01908     /* Have to convert from dbus string array to hal string array 
01909      * since we can't poke at the dbus string array for the reason
01910      * that d-bus use their own memory allocation scheme
01911      */
01912     hal_device_names = malloc (sizeof (char *) * ((*num_devices) + 1));
01913     if (hal_device_names == NULL)
01914         return NULL;
01917     for (i = 0; i < (*num_devices); i++) {
01918         hal_device_names[i] = strdup (device_names[i]);
01919         if (hal_device_names[i] == NULL)
01920             return NULL;
01922     }
01923     hal_device_names[i] = NULL;
01924 
01925     dbus_free_string_array (device_names);
01926 
01927     return hal_device_names;
01928 }
01929 
01936 int
01937 hal_device_property_watch_all ()
01938 {
01939     DBusError error;
01940 
01941     dbus_error_init (&error);
01942 
01943     dbus_bus_add_match (connection,
01944                 "type='signal',"
01945                 "interface='org.freedesktop.Hal.Device',"
01946                 "sender='org.freedesktop.Hal'", &error);
01947     if (dbus_error_is_set (&error)) {
01948         fprintf (stderr, "%s %d : Error subscribing to signals, "
01949              "error=%s\r\n",
01950              __FILE__, __LINE__, error.message);
01951         return 1;
01952     }
01953     return 0;
01954 }
01955 
01956 
01967 int
01968 hal_device_add_property_watch (const char *udi)
01969 {
01970     char buf[512];
01971     DBusError error;
01972 
01973     dbus_error_init (&error);
01974 
01975     snprintf (buf, 512,
01976           "type='signal',"
01977           "interface='org.freedesktop.Hal.Device',"
01978           "sender='org.freedesktop.Hal'," "path=%s", udi);
01979 
01980     dbus_bus_add_match (connection, buf, &error);
01981     if (dbus_error_is_set (&error)) {
01982         fprintf (stderr, "%s %d : Error subscribing to signals, "
01983              "error=%s\r\n",
01984              __FILE__, __LINE__, error.message);
01985         return 1;
01986     }
01987     return 0;
01988 }
01989 
01990 
01997 int
01998 hal_device_remove_property_watch (const char *udi)
01999 {
02000     char buf[512];
02001     DBusError error;
02002 
02003     dbus_error_init (&error);
02004 
02005     snprintf (buf, 512,
02006           "type='signal',"
02007           "interface='org.freedesktop.Hal.Device',"
02008           "sender='org.freedesktop.Hal'," "path=%s", udi);
02009 
02010     dbus_bus_remove_match (connection, buf, &error);
02011     if (dbus_error_is_set (&error)) {
02012         fprintf (stderr, "%s %d : Error unsubscribing to signals, "
02013              "error=%s\r\n",
02014              __FILE__, __LINE__, error.message);
02015         return 1;
02016     }
02017     return 0;
02018 }
02019 
02020 

Generated on Thu Mar 11 21:32:22 2004 for HAL by doxygen 1.3.6-20040222