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

libhal.c

00001 /***************************************************************************
00002  * CVSID: $Id: libhal.c,v 1.18 2004/04/10 16:51: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 
00102 struct LibHalContext_s {
00103     DBusConnection *connection;           
00104     dbus_bool_t is_initialized;           
00105     dbus_bool_t cache_enabled;            
00106     const LibHalFunctions *functions;     
00107 };
00108 
00109 
00116 LibHalPropertySet *
00117 hal_device_get_all_properties (LibHalContext *ctx, const char *udi)
00118 {
00119     DBusError error;
00120     DBusMessage *message;
00121     DBusMessage *reply;
00122     DBusMessageIter iter;
00123     DBusMessageIter dict_iter;
00124     LibHalPropertySet *result;
00125     LibHalProperty **pn;
00126 
00127     message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
00128                         "org.freedesktop.Hal.Device",
00129                         "GetAllProperties");
00130     if (message == NULL) {
00131         fprintf (stderr,
00132              "%s %d : Couldn't allocate D-BUS message\n",
00133              __FILE__, __LINE__);
00134         return NULL;
00135     }
00136 
00137     dbus_error_init (&error);
00138     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
00139                                message, -1,
00140                                &error);
00141     if (dbus_error_is_set (&error)) {
00142         fprintf (stderr, "%s %d: %s raised\n\"%s\"\n\n", __FILE__,
00143              __LINE__, error.name, error.message);
00144         dbus_message_unref (message);
00145         return NULL;
00146     }
00147 
00148     if (reply == NULL) {
00149         dbus_message_unref (message);
00150         return NULL;
00151     }
00152 
00153     dbus_message_iter_init (reply, &iter);
00154 
00155     result = malloc (sizeof (LibHalPropertySet));
00156     if (result == NULL) {
00157         fprintf (stderr, "%s %d : error allocating memory\n",
00158              __FILE__, __LINE__);
00159         dbus_message_unref (message);
00160         dbus_message_unref (reply);
00161         return NULL;
00162     }
00163 
00164 /*
00165     result->properties = malloc(sizeof(LibHalProperty)*result->num_properties);
00166     if( result->properties==NULL )
00167     {
00169     return NULL;
00170     }
00171 */
00172 
00173     pn = &result->properties_head;
00174     result->num_properties = 0;
00175 
00176     dbus_message_iter_init_dict_iterator (&iter, &dict_iter);
00177 
00178     do {
00179         char *dbus_str;
00180         LibHalProperty *p;
00181 
00182         p = malloc (sizeof (LibHalProperty));
00183         if (p == NULL) {
00184             fprintf (stderr,
00185                  "%s %d : error allocating memory\n",
00186                  __FILE__, __LINE__);
00188             return NULL;
00189         }
00190 
00191         *pn = p;
00192         pn = &p->next;
00193         p->next = NULL;
00194         result->num_properties++;
00195 
00196         dbus_str = dbus_message_iter_get_dict_key (&dict_iter);
00197         p->key =
00198             (char *) ((dbus_str != NULL) ? strdup (dbus_str) :
00199                   NULL);
00200         if (p->key == NULL) {
00201             fprintf (stderr,
00202                  "%s %d : error allocating memory\n",
00203                  __FILE__, __LINE__);
00205             return NULL;
00206         }
00207         dbus_free (dbus_str);
00208 
00209         p->type = dbus_message_iter_get_arg_type (&dict_iter);
00210 
00211         switch (p->type) {
00212         case DBUS_TYPE_STRING:
00213             dbus_str =
00214                 dbus_message_iter_get_string (&dict_iter);
00215             p->str_value =
00216                 (char *) ((dbus_str != NULL) ?
00217                       strdup (dbus_str) : NULL);
00218             if (p->str_value == NULL) {
00219                 fprintf (stderr,
00220                      "%s %d : error allocating memory\n",
00221                      __FILE__, __LINE__);
00223                 return NULL;
00224             }
00225             dbus_free (dbus_str);
00226             break;
00227         case DBUS_TYPE_INT32:
00228             p->int_value =
00229                 dbus_message_iter_get_int32 (&dict_iter);
00230             break;
00231         case DBUS_TYPE_DOUBLE:
00232             p->double_value =
00233                 dbus_message_iter_get_double (&dict_iter);
00234             break;
00235         case DBUS_TYPE_BOOLEAN:
00236             p->bool_value =
00237                 dbus_message_iter_get_boolean (&dict_iter);
00238             break;
00239 
00240         default:
00242             break;
00243         }
00244 
00245     }
00246     while (dbus_message_iter_has_next (&dict_iter) &&
00247            dbus_message_iter_next (&dict_iter));
00248 
00249     dbus_message_unref (message);
00250     dbus_message_unref (reply);
00251 
00252     return result;
00253 }
00254 
00259 void
00260 hal_free_property_set (LibHalPropertySet * set)
00261 {
00262     LibHalProperty *p;
00263     LibHalProperty *q;
00264 
00265     for (p = set->properties_head; p != NULL; p = q) {
00266         free (p->key);
00267         if (p->type == DBUS_TYPE_STRING)
00268             free (p->str_value);
00269         q = p->next;
00270         free (p);
00271     }
00272     free (set);
00273 }
00274 
00280 void
00281 hal_psi_init (LibHalPropertySetIterator * iter, LibHalPropertySet * set)
00282 {
00283     iter->set = set;
00284     iter->index = 0;
00285     iter->cur_prop = set->properties_head;
00286 }
00287 
00293 dbus_bool_t
00294 hal_psi_has_more (LibHalPropertySetIterator * iter)
00295 {
00296     return iter->index < iter->set->num_properties;
00297 }
00298 
00303 void
00304 hal_psi_next (LibHalPropertySetIterator * iter)
00305 {
00306     iter->index++;
00307     iter->cur_prop = iter->cur_prop->next;
00308 }
00309 
00316 int
00317 hal_psi_get_type (LibHalPropertySetIterator * iter)
00318 {
00319     return iter->cur_prop->type;
00320 }
00321 
00330 char *
00331 hal_psi_get_key (LibHalPropertySetIterator * iter)
00332 {
00333     return iter->cur_prop->key;
00334 }
00335 
00344 char *
00345 hal_psi_get_string (LibHalPropertySetIterator * iter)
00346 {
00347     return iter->cur_prop->str_value;
00348 }
00349 
00355 dbus_int32_t
00356 hal_psi_get_int (LibHalPropertySetIterator * iter)
00357 {
00358     return iter->cur_prop->int_value;
00359 }
00360 
00366 double
00367 hal_psi_get_double (LibHalPropertySetIterator * iter)
00368 {
00369     return iter->cur_prop->double_value;
00370 }
00371 
00377 dbus_bool_t
00378 hal_psi_get_bool (LibHalPropertySetIterator * iter)
00379 {
00380     return iter->cur_prop->bool_value;
00381 }
00382 
00383 
00384 static DBusHandlerResult
00385 filter_func (DBusConnection * connection,
00386          DBusMessage * message, void *user_data)
00387 {
00388     const char *object_path;
00389     DBusError error;
00390     LibHalContext *ctx = (LibHalContext *) user_data;
00391 
00392     dbus_error_init (&error);
00393 
00394     object_path = dbus_message_get_path (message);
00395 
00396     /*printf("*** in filter_func, object_path=%s\n", object_path); */
00397 
00398     if (dbus_message_is_signal (message, "org.freedesktop.Hal.Manager",
00399                     "DeviceAdded")) {
00400         char *udi;
00401         if (dbus_message_get_args (message, &error,
00402                        DBUS_TYPE_STRING, &udi,
00403                        DBUS_TYPE_INVALID)) {
00404             if (ctx->functions->device_added != NULL) {
00405                 ctx->functions->device_added (ctx, udi);
00406                 dbus_free (udi);
00407             }
00408         }
00409     } else
00410         if (dbus_message_is_signal
00411         (message, "org.freedesktop.Hal.Manager",
00412          "DeviceRemoved")) {
00413         char *udi;
00414         if (dbus_message_get_args (message, &error,
00415                        DBUS_TYPE_STRING, &udi,
00416                        DBUS_TYPE_INVALID)) {
00417             if (ctx->functions->device_removed != NULL) {
00418                 ctx->functions->device_removed (ctx, udi);
00419                 dbus_free (udi);
00420             }
00421         }
00422     } else
00423         if (dbus_message_is_signal
00424         (message, "org.freedesktop.Hal.Manager",
00425          "NewCapability")) {
00426         char *udi;
00427         char *capability;
00428         if (dbus_message_get_args (message, &error,
00429                        DBUS_TYPE_STRING, &udi,
00430                        DBUS_TYPE_STRING, &capability,
00431                        DBUS_TYPE_INVALID)) {
00432             if (ctx->functions->device_new_capability != NULL) {
00433                 ctx->functions->device_new_capability (ctx, 
00434                                        udi,
00435                                   capability);
00436                 dbus_free (udi);
00437                 dbus_free (capability);
00438             }
00439         }
00440     } else
00441         if (dbus_message_is_signal
00442         (message, "org.freedesktop.Hal.Device", "Condition")) {
00443         if (ctx->functions->device_condition != NULL) {
00444             DBusMessageIter iter;
00445             char *condition_name;
00446 
00447             dbus_message_iter_init (message, &iter);
00448             condition_name =
00449                 dbus_message_iter_get_string (&iter);
00450 
00451             ctx->functions->device_condition (ctx, 
00452                               object_path,
00453                               condition_name,
00454                               message);
00455 
00456             dbus_free (condition_name);
00457         }
00458     } else
00459         if (dbus_message_is_signal
00460         (message, "org.freedesktop.Hal.Device",
00461          "PropertyModified")) {
00462         if (ctx->functions->device_property_modified != NULL) {
00463             int i;
00464             char *key;
00465             dbus_bool_t removed, added;
00466             int num_modifications;
00467             DBusMessageIter iter;
00468 
00469             dbus_message_iter_init (message, &iter);
00470             num_modifications =
00471                 dbus_message_iter_get_int32 (&iter);
00472             dbus_message_iter_next (&iter);
00473 
00474 
00475             for (i = 0; i < num_modifications; i++) {
00476 
00477                 key = dbus_message_iter_get_string (&iter);
00478                 dbus_message_iter_next (&iter);
00479                 removed =
00480                     dbus_message_iter_get_boolean (&iter);
00481                 dbus_message_iter_next (&iter);
00482                 added =
00483                     dbus_message_iter_get_boolean (&iter);
00484                 dbus_message_iter_next (&iter);
00485 
00486                 ctx->functions->
00487                     device_property_modified (ctx, 
00488                                   object_path,
00489                                   key, removed,
00490                                   added);
00491 
00492                 dbus_free (key);
00493             }
00494 
00495         }
00496     }
00497 
00498     return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
00499 }
00500 
00501 static LibHalFunctions hal_null_functions = {
00502     NULL /*mainloop_integration */ ,
00503     NULL /*device_added */ ,
00504     NULL /*device_removed */ ,
00505     NULL /*device_new_capability */ ,
00506     NULL /*device_lost_capability */ ,
00507     NULL /*property_modified */ ,
00508     NULL /*device_condition */
00509 };
00510 
00529 LibHalContext*
00530 hal_initialize (const LibHalFunctions * cb_functions,
00531         dbus_bool_t use_cache)
00532 {
00533     DBusError error;
00534     LibHalContext *ctx;
00535     
00536     ctx = malloc (sizeof (LibHalContext));
00537     if (ctx == NULL) {
00538         fprintf (stderr, "%s %d : Cannot allocated %d bytes!\n",
00539              __FILE__, __LINE__, sizeof (LibHalContext));
00540         return NULL;
00541     }
00542 
00543     ctx->cache_enabled = use_cache;
00544 
00545     ctx->functions = cb_functions;
00546     /* allow caller to pass NULL */
00547     if (ctx->functions == NULL)
00548         ctx->functions = &hal_null_functions;
00549 
00550     /* connect to hald service on the system bus */
00551     dbus_error_init (&error);
00552     ctx->connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
00553     if (ctx->connection == NULL) {
00554         fprintf (stderr,
00555              "%s %d : Error connecting to system bus: %s\n",
00556              __FILE__, __LINE__, error.message);
00557         dbus_error_free (&error);
00558         return NULL;
00559     }
00560 
00561     if (ctx->functions->main_loop_integration != NULL) {
00562 
00563         ctx->functions->main_loop_integration (ctx, ctx->connection);
00564     }
00565 
00566     if (!dbus_connection_add_filter
00567         (ctx->connection, filter_func, ctx, NULL)) {
00568         fprintf (stderr,
00569              "%s %d : Error creating connection handler\r\n",
00570              __FILE__, __LINE__);
00572         return NULL;
00573     }
00574 
00575     dbus_bus_add_match (ctx->connection,
00576                 "type='signal',"
00577                 "interface='org.freedesktop.Hal.Manager',"
00578                 "sender='org.freedesktop.Hal',"
00579                 "path='/org/freedesktop/Hal/Manager'", &error);
00580     if (dbus_error_is_set (&error)) {
00581         fprintf (stderr, "%s %d : Error subscribing to signals, "
00582              "error=%s\r\n",
00583              __FILE__, __LINE__, error.message);
00585         return NULL;
00586     }
00587 
00588     ctx->is_initialized = TRUE;
00589 
00590     return ctx;
00591 }
00592 
00598 int
00599 hal_shutdown (LibHalContext *ctx)
00600 {
00601     if (!ctx->is_initialized)
00602         return 1;
00603 
00605     free (ctx);
00606     return 0;
00607 }
00608 
00617 char **
00618 hal_get_all_devices (LibHalContext *ctx, int *num_devices)
00619 {
00620     int i;
00621     DBusError error;
00622     DBusMessage *message;
00623     DBusMessage *reply;
00624     DBusMessageIter iter;
00625     char **device_names;
00626     char **hal_device_names;
00627 
00628     message = dbus_message_new_method_call ("org.freedesktop.Hal",
00629                         "/org/freedesktop/Hal/Manager",
00630                         "org.freedesktop.Hal.Manager",
00631                         "GetAllDevices");
00632     if (message == NULL) {
00633         fprintf (stderr,
00634              "%s %d : Couldn't allocate D-BUS message\n",
00635              __FILE__, __LINE__);
00636         return NULL;
00637     }
00638 
00639     dbus_error_init (&error);
00640     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
00641                                message, -1,
00642                                &error);
00643     if (dbus_error_is_set (&error)) {
00644         fprintf (stderr, "%s %d : %s raised\n\"%s\"\n\n", __FILE__,
00645              __LINE__, error.name, error.message);
00646         dbus_message_unref (message);
00647         return NULL;
00648     }
00649 
00650     if (reply == NULL) {
00651         dbus_message_unref (message);
00652         return NULL;
00653     }
00654 
00655     /* now analyze reply */
00656     dbus_message_iter_init (reply, &iter);
00657     if (!dbus_message_iter_get_string_array (&iter,
00658                          &device_names,
00659                          num_devices)) {
00660         fprintf (stderr, "%s %d : wrong reply from hald\n",
00661              __FILE__, __LINE__);
00662         return NULL;
00663     }
00664 
00665     dbus_message_unref (reply);
00666     dbus_message_unref (message);
00667 
00668     /* Have to convert from dbus string array to hal string array 
00669      * since we can't poke at the dbus string array for the reason
00670      * that d-bus use their own memory allocation scheme
00671      */
00672     hal_device_names = malloc (sizeof (char *) * ((*num_devices) + 1));
00673     if (hal_device_names == NULL)
00674         return NULL;
00677     for (i = 0; i < (*num_devices); i++) {
00678         hal_device_names[i] = strdup (device_names[i]);
00679         if (hal_device_names[i] == NULL) {
00680             fprintf (stderr,
00681                  "%s %d : error allocating memory\n",
00682                  __FILE__, __LINE__);
00684             return NULL;
00685         }
00686     }
00687     hal_device_names[i] = NULL;
00688 
00689     dbus_free_string_array (device_names);
00690 
00691     return hal_device_names;
00692 }
00693 
00702 int
00703 hal_device_get_property_type (LibHalContext *ctx, 
00704                   const char *udi, const char *key)
00705 {
00706     DBusError error;
00707     DBusMessage *message;
00708     DBusMessage *reply;
00709     DBusMessageIter iter;
00710     int type;
00711 
00712     message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
00713                         "org.freedesktop.Hal.Device",
00714                         "GetPropertyType");
00715     if (message == NULL) {
00716         fprintf (stderr,
00717              "%s %d : Couldn't allocate D-BUS message\n",
00718              __FILE__, __LINE__);
00719         return DBUS_TYPE_NIL;
00720     }
00721 
00722     dbus_message_iter_init (message, &iter);
00723     dbus_message_iter_append_string (&iter, key);
00724     dbus_error_init (&error);
00725     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
00726                                message, -1,
00727                                &error);
00728     if (dbus_error_is_set (&error)) {
00729         fprintf (stderr, "%s %d : %s raised\n\"%s\"\n\n", __FILE__,
00730              __LINE__, error.name, error.message);
00731         dbus_message_unref (message);
00732         return DBUS_TYPE_NIL;
00733     }
00734     if (reply == NULL) {
00735         dbus_message_unref (message);
00736         return DBUS_TYPE_NIL;
00737     }
00738 
00739     dbus_message_iter_init (reply, &iter);
00740     type = dbus_message_iter_get_int32 (&iter);
00741 
00742     dbus_message_unref (message);
00743     dbus_message_unref (reply);
00744 
00745     return type;
00746 }
00747 
00758 char *
00759 hal_device_get_property_string (LibHalContext *ctx,
00760                 const char *udi, const char *key)
00761 {
00762     DBusError error;
00763     DBusMessage *message;
00764     DBusMessage *reply;
00765     DBusMessageIter iter;
00766     char *value;
00767     char *dbus_str;
00768 
00769     message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
00770                         "org.freedesktop.Hal.Device",
00771                         "GetPropertyString");
00772     if (message == NULL) {
00773         fprintf (stderr,
00774              "%s %d : Couldn't allocate D-BUS message\n",
00775              __FILE__, __LINE__);
00776         return NULL;
00777     }
00778 
00779     dbus_message_iter_init (message, &iter);
00780     dbus_message_iter_append_string (&iter, key);
00781     dbus_error_init (&error);
00782     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
00783                                message, -1,
00784                                &error);
00785     if (dbus_error_is_set (&error)) {
00786         fprintf (stderr, "%s %d : Error sending msg: %s\n",
00787              __FILE__, __LINE__, error.message);
00788         dbus_message_unref (message);
00789         return NULL;
00790     }
00791     if (reply == NULL) {
00792         dbus_message_unref (message);
00793         return NULL;
00794     }
00795 
00796     dbus_message_iter_init (reply, &iter);
00797 
00798     /* now analyze reply */
00799     if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_NIL) {
00800         fprintf (stderr,
00801              "%s %d : property '%s' for device '%s' does not "
00802              "exist\n", __FILE__, __LINE__, key, udi);
00803         dbus_message_unref (message);
00804         dbus_message_unref (reply);
00805         return NULL;
00806     } else if (dbus_message_iter_get_arg_type (&iter) !=
00807            DBUS_TYPE_STRING) {
00808         fprintf (stderr,
00809              "%s %d : property '%s' for device '%s' is not "
00810              "of type string\n", __FILE__, __LINE__, key, udi);
00811         dbus_message_unref (message);
00812         dbus_message_unref (reply);
00813         return NULL;
00814     }
00815 
00816     dbus_str = dbus_message_iter_get_string (&iter);
00817     value = (char *) ((dbus_str != NULL) ? strdup (dbus_str) : NULL);
00818     if (value == NULL) {
00819         fprintf (stderr, "%s %d : error allocating memory\n",
00820              __FILE__, __LINE__);
00822         return NULL;
00823     }
00824     dbus_free (dbus_str);
00825 
00826     dbus_message_unref (message);
00827     dbus_message_unref (reply);
00828     return value;
00829 }
00830 
00837 dbus_int32_t
00838 hal_device_get_property_int (LibHalContext *ctx, 
00839                  const char *udi, const char *key)
00840 {
00841     DBusError error;
00842     DBusMessage *message;
00843     DBusMessage *reply;
00844     DBusMessageIter iter;
00845     dbus_int32_t value;
00846 
00847     message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
00848                         "org.freedesktop.Hal.Device",
00849                         "GetPropertyInteger");
00850     if (message == NULL) {
00851         fprintf (stderr,
00852              "%s %d : Couldn't allocate D-BUS message\n",
00853              __FILE__, __LINE__);
00854         return -1;
00855     }
00856 
00857     dbus_message_iter_init (message, &iter);
00858     dbus_message_iter_append_string (&iter, key);
00859     dbus_error_init (&error);
00860     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
00861                                message, -1,
00862                                &error);
00863     if (dbus_error_is_set (&error)) {
00864         fprintf (stderr, "%s %d : Error sending msg: %s\n",
00865              __FILE__, __LINE__, error.message);
00866         dbus_message_unref (message);
00867         return -1;
00868     }
00869     if (reply == NULL) {
00870         dbus_message_unref (message);
00871         return -1;
00872     }
00873 
00874     dbus_message_iter_init (reply, &iter);
00875 
00876     /* now analyze reply */
00877     if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_NIL) {
00878         /* property didn't exist */
00879         fprintf (stderr,
00880              "%s %d : property '%s' for device '%s' does not "
00881              "exist\n", __FILE__, __LINE__, key, udi);
00882         dbus_message_unref (message);
00883         dbus_message_unref (reply);
00884         return -1;
00885     } else if (dbus_message_iter_get_arg_type (&iter) !=
00886            DBUS_TYPE_INT32) {
00887         fprintf (stderr,
00888              "%s %d : property '%s' for device '%s' is not "
00889              "of type integer\n", __FILE__, __LINE__, key,
00890              udi);
00891         dbus_message_unref (message);
00892         dbus_message_unref (reply);
00893         return -1;
00894     }
00895     value = dbus_message_iter_get_int32 (&iter);
00896 
00897     dbus_message_unref (message);
00898     dbus_message_unref (reply);
00899     return value;
00900 }
00901 
00908 double
00909 hal_device_get_property_double (LibHalContext *ctx, 
00910                 const char *udi, const char *key)
00911 {
00912     DBusError error;
00913     DBusMessage *message;
00914     DBusMessage *reply;
00915     DBusMessageIter iter;
00916     double value;
00917 
00918     message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
00919                         "org.freedesktop.Hal.Device",
00920                         "GetPropertyDouble");
00921     if (message == NULL) {
00922         fprintf (stderr,
00923              "%s %d : Couldn't allocate D-BUS message\n",
00924              __FILE__, __LINE__);
00925         return -1.0f;
00926     }
00927 
00928     dbus_message_iter_init (message, &iter);
00929     dbus_message_iter_append_string (&iter, key);
00930     dbus_error_init (&error);
00931     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
00932                                message, -1,
00933                                &error);
00934     if (dbus_error_is_set (&error)) {
00935         fprintf (stderr, "%s %d : Error sending msg: %s\n",
00936              __FILE__, __LINE__, error.message);
00937         dbus_message_unref (message);
00938         return -1.0f;
00939     }
00940     if (reply == NULL) {
00941         dbus_message_unref (message);
00942         return -1.0f;
00943     }
00944 
00945     dbus_message_iter_init (reply, &iter);
00946 
00947     /* now analyze reply */
00948     if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_NIL) {
00949         /* property didn't exist */
00950         fprintf (stderr,
00951              "%s %d : property '%s' for device '%s' does not "
00952              "exist\n", __FILE__, __LINE__, key, udi);
00953         dbus_message_unref (message);
00954         dbus_message_unref (reply);
00955         return -1.0f;
00956     } else if (dbus_message_iter_get_arg_type (&iter) !=
00957            DBUS_TYPE_DOUBLE) {
00958         fprintf (stderr,
00959              "%s %d : property '%s' for device '%s' is not "
00960              "of type double\n", __FILE__, __LINE__, key, udi);
00961         dbus_message_unref (message);
00962         dbus_message_unref (reply);
00963         return -1.0f;
00964     }
00965     value = dbus_message_iter_get_double (&iter);
00966 
00967     dbus_message_unref (message);
00968     dbus_message_unref (reply);
00969     return (double) value;
00970 }
00971 
00978 dbus_bool_t
00979 hal_device_get_property_bool (LibHalContext *ctx, 
00980                   const char *udi, const char *key)
00981 {
00982     DBusError error;
00983     DBusMessage *message;
00984     DBusMessage *reply;
00985     DBusMessageIter iter;
00986     double value;
00987 
00988     message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
00989                         "org.freedesktop.Hal.Device",
00990                         "GetPropertyBoolean");
00991     if (message == NULL) {
00992         fprintf (stderr,
00993              "%s %d : Couldn't allocate D-BUS message\n",
00994              __FILE__, __LINE__);
00995         return FALSE;
00996     }
00997 
00998     dbus_message_iter_init (message, &iter);
00999     dbus_message_iter_append_string (&iter, key);
01000     dbus_error_init (&error);
01001     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01002                                message, -1,
01003                                &error);
01004     if (dbus_error_is_set (&error)) {
01005         fprintf (stderr, "%s %d : Error sending msg: %s\n",
01006              __FILE__, __LINE__, error.message);
01007         dbus_message_unref (message);
01008         return FALSE;
01009     }
01010     if (reply == NULL) {
01011         dbus_message_unref (message);
01012         return FALSE;
01013     }
01014 
01015     dbus_message_iter_init (reply, &iter);
01016 
01017     /* now analyze reply */
01018     if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_NIL) {
01019         /* property didn't exist */
01020         fprintf (stderr,
01021              "%s %d : property '%s' for device '%s' does not "
01022              "exist\n", __FILE__, __LINE__, key, udi);
01023         dbus_message_unref (message);
01024         dbus_message_unref (reply);
01025         return FALSE;
01026     } else if (dbus_message_iter_get_arg_type (&iter) !=
01027            DBUS_TYPE_BOOLEAN) {
01028         fprintf (stderr,
01029              "%s %d : property '%s' for device '%s' is not "
01030              "of type bool\n", __FILE__, __LINE__, key, udi);
01031         dbus_message_unref (message);
01032         dbus_message_unref (reply);
01033         return FALSE;
01034     }
01035     value = dbus_message_iter_get_boolean (&iter);
01036 
01037     dbus_message_unref (message);
01038     dbus_message_unref (reply);
01039     return value;
01040 }
01041 
01042 
01043 /* generic helper */
01044 static int
01045 hal_device_set_property_helper (LibHalContext *ctx, 
01046                 const char *udi,
01047                 const char *key,
01048                 int type,
01049                 const char *str_value,
01050                 dbus_int32_t int_value,
01051                 double double_value,
01052                 dbus_bool_t bool_value)
01053 {
01054     DBusError error;
01055     DBusMessage *message;
01056     DBusMessage *reply;
01057     DBusMessageIter iter;
01058     char *method_name = NULL;
01059 
01062     switch (type) {
01063     case DBUS_TYPE_NIL:
01064         method_name = "RemoveProperty";
01065         break;
01066     case DBUS_TYPE_STRING:
01067         method_name = "SetPropertyString";
01068         break;
01069     case DBUS_TYPE_INT32:
01070         method_name = "SetPropertyInteger";
01071         break;
01072     case DBUS_TYPE_DOUBLE:
01073         method_name = "SetPropertyDouble";
01074         break;
01075     case DBUS_TYPE_BOOLEAN:
01076         method_name = "SetPropertyBoolean";
01077         break;
01078 
01079     default:
01080         /* cannot happen; is not callable from outside this file */
01081         break;
01082     }
01083 
01084     message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
01085                         "org.freedesktop.Hal.Device",
01086                         method_name);
01087     if (message == NULL) {
01088         fprintf (stderr,
01089              "%s %d : Couldn't allocate D-BUS message\n",
01090              __FILE__, __LINE__);
01091         return FALSE;
01092     }
01093 
01094     dbus_message_iter_init (message, &iter);
01095     dbus_message_iter_append_string (&iter, key);
01096     switch (type) {
01097     case DBUS_TYPE_NIL:
01098         dbus_message_iter_append_nil (&iter);
01099         break;
01100     case DBUS_TYPE_STRING:
01101         dbus_message_iter_append_string (&iter, str_value);
01102         break;
01103     case DBUS_TYPE_INT32:
01104         dbus_message_iter_append_int32 (&iter, int_value);
01105         break;
01106     case DBUS_TYPE_DOUBLE:
01107         dbus_message_iter_append_double (&iter, double_value);
01108         break;
01109     case DBUS_TYPE_BOOLEAN:
01110         dbus_message_iter_append_boolean (&iter, bool_value);
01111         break;
01112     }
01113 
01114     dbus_error_init (&error);
01115     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01116                                message, -1,
01117                                &error);
01118     if (dbus_error_is_set (&error)) {
01119         fprintf (stderr, "%s %d: %s raised\n\"%s\"\n\n", __FILE__,
01120              __LINE__, error.name, error.message);
01121         dbus_message_unref (message);
01122         return FALSE;
01123     }
01124 
01125     if (reply == NULL) {
01126         dbus_message_unref (message);
01127         return FALSE;
01128     }
01129 
01130     return TRUE;
01131 }
01132 
01142 dbus_bool_t
01143 hal_device_set_property_string (LibHalContext *ctx, 
01144                 const char *udi,
01145                 const char *key, const char *value)
01146 {
01147     return hal_device_set_property_helper (ctx, udi, key,
01148                            DBUS_TYPE_STRING,
01149                            value, 0, 0.0f, FALSE);
01150 }
01151 
01161 dbus_bool_t
01162 hal_device_set_property_int (LibHalContext *ctx, const char *udi,
01163                  const char *key, dbus_int32_t value)
01164 {
01165     return hal_device_set_property_helper (ctx, udi, key,
01166                            DBUS_TYPE_INT32,
01167                            NULL, value, 0.0f, FALSE);
01168 }
01169 
01179 dbus_bool_t
01180 hal_device_set_property_double (LibHalContext *ctx, const char *udi,
01181                 const char *key, double value)
01182 {
01183     return hal_device_set_property_helper (ctx, udi, key,
01184                            DBUS_TYPE_DOUBLE,
01185                            NULL, 0, value, FALSE);
01186 }
01187 
01197 dbus_bool_t
01198 hal_device_set_property_bool (LibHalContext *ctx, const char *udi,
01199                   const char *key, dbus_bool_t value)
01200 {
01201     return hal_device_set_property_helper (ctx, udi, key,
01202                            DBUS_TYPE_BOOLEAN,
01203                            NULL, 0, 0.0f, value);
01204 }
01205 
01206 
01214 dbus_bool_t
01215 hal_device_remove_property (LibHalContext *ctx, 
01216                 const char *udi, const char *key)
01217 {
01218     return hal_device_set_property_helper (ctx, udi, key, DBUS_TYPE_NIL,    
01219                            /* DBUS_TYPE_NIL means remove */
01220                            NULL, 0, 0.0f, FALSE);
01221 }
01222 
01223 
01234 char *
01235 hal_agent_new_device (LibHalContext *ctx)
01236 {
01237     DBusError error;
01238     DBusMessage *message;
01239     DBusMessage *reply;
01240     DBusMessageIter iter;
01241     char *value;
01242     char *dbus_str;
01243 
01244     message = dbus_message_new_method_call ("org.freedesktop.Hal",
01245                         "/org/freedesktop/Hal/Manager",
01246                         "org.freedesktop.Hal.AgentManager",
01247                         "NewDevice");
01248     if (message == NULL) {
01249         fprintf (stderr,
01250              "%s %d : Couldn't allocate D-BUS message\n",
01251              __FILE__, __LINE__);
01252         return NULL;
01253     }
01254 
01255     dbus_error_init (&error);
01256     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01257                                message, -1,
01258                                &error);
01259     if (dbus_error_is_set (&error)) {
01260         fprintf (stderr, "%s %d : Error sending msg: %s\n",
01261              __FILE__, __LINE__, error.message);
01262         dbus_message_unref (message);
01263         return NULL;
01264     }
01265     if (reply == NULL) {
01266         dbus_message_unref (message);
01267         return NULL;
01268     }
01269 
01270     dbus_message_iter_init (reply, &iter);
01271 
01272     /* now analyze reply */
01273     if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING) {
01274         fprintf (stderr,
01275              "%s %d : expected a string in reply to NewDevice\n",
01276              __FILE__, __LINE__);
01277         dbus_message_unref (message);
01278         dbus_message_unref (reply);
01279         return NULL;
01280     }
01281 
01282     dbus_str = dbus_message_iter_get_string (&iter);
01283     value = (char *) ((dbus_str != NULL) ? strdup (dbus_str) : NULL);
01284     if (value == NULL) {
01285         fprintf (stderr, "%s %d : error allocating memory\n",
01286              __FILE__, __LINE__);
01288         return NULL;
01289     }
01290     dbus_free (dbus_str);
01291 
01292     dbus_message_unref (message);
01293     dbus_message_unref (reply);
01294     return value;
01295 }
01296 
01297 
01315 dbus_bool_t
01316 hal_agent_commit_to_gdl (LibHalContext *ctx, 
01317              const char *temp_udi, const char *udi)
01318 {
01319     DBusError error;
01320     DBusMessage *message;
01321     DBusMessage *reply;
01322     DBusMessageIter iter;
01323 
01324     message = dbus_message_new_method_call ("org.freedesktop.Hal",
01325                         "/org/freedesktop/Hal/Manager",
01326                         "org.freedesktop.Hal.AgentManager",
01327                         "CommitToGdl");
01328     if (message == NULL) {
01329         fprintf (stderr,
01330              "%s %d : Couldn't allocate D-BUS message\n",
01331              __FILE__, __LINE__);
01332         return FALSE;
01333     }
01334 
01335     dbus_message_iter_init (message, &iter);
01336     dbus_message_iter_append_string (&iter, temp_udi);
01337     dbus_message_iter_append_string (&iter, udi);
01338 
01339     dbus_error_init (&error);
01340     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01341                                message, -1,
01342                                &error);
01343     if (dbus_error_is_set (&error)) {
01344         if (dbus_error_has_name
01345             (&error, "org.freedesktop.Hal.UdiInUse"))
01346             return FALSE;
01347         fprintf (stderr, "%s %d : Error sending msg: %s\n",
01348              __FILE__, __LINE__, error.message);
01349         dbus_message_unref (message);
01350         return FALSE;
01351     }
01352     if (reply == NULL) {
01353         dbus_message_unref (message);
01354         return FALSE;
01355     }
01356 
01357     dbus_message_unref (message);
01358     dbus_message_unref (reply);
01359     return TRUE;
01360 }
01361 
01372 dbus_bool_t
01373 hal_agent_remove_device (LibHalContext *ctx, const char *udi)
01374 {
01375     DBusError error;
01376     DBusMessage *message;
01377     DBusMessage *reply;
01378     DBusMessageIter iter;
01379 
01380     message = dbus_message_new_method_call ("org.freedesktop.Hal",
01381                         "/org/freedesktop/Hal/Manager",
01382                         "org.freedesktop.Hal.AgentManager",
01383                         "Remove");
01384     if (message == NULL) {
01385         fprintf (stderr,
01386              "%s %d : Couldn't allocate D-BUS message\n",
01387              __FILE__, __LINE__);
01388         return FALSE;
01389     }
01390 
01391     dbus_message_iter_init (message, &iter);
01392     dbus_message_iter_append_string (&iter, udi);
01393 
01394     dbus_error_init (&error);
01395     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01396                                message, -1,
01397                                &error);
01398     if (dbus_error_is_set (&error)) {
01399         fprintf (stderr, "%s %d : Error sending msg: %s\n",
01400              __FILE__, __LINE__, error.message);
01401         dbus_message_unref (message);
01402         return FALSE;
01403     }
01404     if (reply == NULL) {
01405         dbus_message_unref (message);
01406         return FALSE;
01407     }
01408 
01409     dbus_message_unref (message);
01410     dbus_message_unref (reply);
01411     return TRUE;
01412 }
01413 
01419 dbus_bool_t
01420 hal_device_exists (LibHalContext *ctx, const char *udi)
01421 {
01422     DBusError error;
01423     DBusMessage *message;
01424     DBusMessage *reply;
01425     DBusMessageIter iter;
01426     dbus_bool_t value;
01427 
01428     message = dbus_message_new_method_call ("org.freedesktop.Hal",
01429                         "/org/freedesktop/Hal/Manager",
01430                         "org.freedesktop.Hal.Manager",
01431                         "DeviceExists");
01432     if (message == NULL) {
01433         fprintf (stderr,
01434              "%s %d : Couldn't allocate D-BUS message\n",
01435              __FILE__, __LINE__);
01436         return FALSE;
01437     }
01438 
01439     dbus_message_iter_init (message, &iter);
01440     dbus_message_iter_append_string (&iter, udi);
01441 
01442     dbus_error_init (&error);
01443     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01444                                message, -1,
01445                                &error);
01446     if (dbus_error_is_set (&error)) {
01447         fprintf (stderr, "%s %d : Error sending msg: %s\n",
01448              __FILE__, __LINE__, error.message);
01449         dbus_message_unref (message);
01450         return FALSE;
01451     }
01452     if (reply == NULL) {
01453         dbus_message_unref (message);
01454         return FALSE;
01455     }
01456 
01457     dbus_message_iter_init (reply, &iter);
01458 
01459     /* now analyze reply */
01460     if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_BOOLEAN) {
01461         fprintf (stderr,
01462              "%s %d : expected a bool in reply to DeviceExists\n",
01463              __FILE__, __LINE__);
01464         dbus_message_unref (message);
01465         dbus_message_unref (reply);
01466         return FALSE;
01467     }
01468 
01469     value = dbus_message_iter_get_boolean (&iter);
01470 
01471     dbus_message_unref (message);
01472     dbus_message_unref (reply);
01473     return value;
01474 }
01475 
01482 dbus_bool_t
01483 hal_device_property_exists (LibHalContext *ctx, 
01484                 const char *udi, const char *key)
01485 {
01486     DBusError error;
01487     DBusMessage *message;
01488     DBusMessage *reply;
01489     DBusMessageIter iter;
01490     dbus_bool_t value;
01491 
01492     message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
01493                         "org.freedesktop.Hal.Device",
01494                         "PropertyExists");
01495     if (message == NULL) {
01496         fprintf (stderr,
01497              "%s %d : Couldn't allocate D-BUS message\n",
01498              __FILE__, __LINE__);
01499         return FALSE;
01500     }
01501 
01502     dbus_message_iter_init (message, &iter);
01503     dbus_message_iter_append_string (&iter, key);
01504 
01505     dbus_error_init (&error);
01506     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01507                                message, -1,
01508                                &error);
01509     if (dbus_error_is_set (&error)) {
01510         fprintf (stderr, "%s %d : Error sending msg: %s\n",
01511              __FILE__, __LINE__, error.message);
01512         dbus_message_unref (message);
01513         return FALSE;
01514     }
01515     if (reply == NULL) {
01516         dbus_message_unref (message);
01517         return FALSE;
01518     }
01519 
01520     dbus_message_iter_init (reply, &iter);
01521 
01522     /* now analyse reply */
01523     if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_BOOLEAN) {
01524         fprintf (stderr, "%s %d : expected a bool in reply to "
01525              "PropertyExists\n", __FILE__, __LINE__);
01526         dbus_message_unref (message);
01527         dbus_message_unref (reply);
01528         return FALSE;
01529     }
01530 
01531     value = dbus_message_iter_get_boolean (&iter);
01532 
01533     dbus_message_unref (message);
01534     dbus_message_unref (reply);
01535     return value;
01536 }
01537 
01544 dbus_bool_t
01545 hal_agent_merge_properties (LibHalContext *ctx, 
01546                 const char *target_udi, const char *source_udi)
01547 {
01548     DBusError error;
01549     DBusMessage *message;
01550     DBusMessage *reply;
01551     DBusMessageIter iter;
01552 
01553     message = dbus_message_new_method_call ("org.freedesktop.Hal",
01554                         "/org/freedesktop/Hal/Manager",
01555                         "org.freedesktop.Hal.AgentManager",
01556                         "MergeProperties");
01557     if (message == NULL) {
01558         fprintf (stderr,
01559              "%s %d : Couldn't allocate D-BUS message\n",
01560              __FILE__, __LINE__);
01561         return FALSE;
01562     }
01563 
01564     dbus_message_iter_init (message, &iter);
01565     dbus_message_iter_append_string (&iter, target_udi);
01566     dbus_message_iter_append_string (&iter, source_udi);
01567 
01568     dbus_error_init (&error);
01569     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01570                                message, -1,
01571                                &error);
01572     if (dbus_error_is_set (&error)) {
01573         if (dbus_error_has_name
01574             (&error, "org.freedesktop.Hal.NoSuchDevice"))
01575             return FALSE;
01576         fprintf (stderr, "%s %d : Error sending msg: %s\n",
01577              __FILE__, __LINE__, error.message);
01578         dbus_message_unref (message);
01579         return FALSE;
01580     }
01581     if (reply == NULL) {
01582         dbus_message_unref (message);
01583         return FALSE;
01584     }
01585 
01586     dbus_message_unref (message);
01587     dbus_message_unref (reply);
01588     return TRUE;
01589 }
01590 
01609 dbus_bool_t
01610 hal_agent_device_matches (LibHalContext *ctx, 
01611               const char *udi1, const char *udi2,
01612               const char *namespace)
01613 {
01614     DBusError error;
01615     DBusMessage *message;
01616     DBusMessage *reply;
01617     DBusMessageIter iter;
01618     dbus_bool_t value;
01619 
01620     message = dbus_message_new_method_call ("org.freedesktop.Hal",
01621                         "/org/freedesktop/Hal/Manager",
01622                         "org.freedesktop.Hal.AgentManager",
01623                         "DeviceMatches");
01624     if (message == NULL) {
01625         fprintf (stderr,
01626              "%s %d : Couldn't allocate D-BUS message\n",
01627              __FILE__, __LINE__);
01628         return FALSE;
01629     }
01630 
01631     dbus_message_iter_init (message, &iter);
01632     dbus_message_iter_append_string (&iter, udi1);
01633     dbus_message_iter_append_string (&iter, udi2);
01634     dbus_message_iter_append_string (&iter, namespace);
01635 
01636     dbus_error_init (&error);
01637     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01638                                message, -1,
01639                                &error);
01640     if (dbus_error_is_set (&error)) {
01641         fprintf (stderr, "%s %d : Error sending msg: %s\n",
01642              __FILE__, __LINE__, error.message);
01643         dbus_message_unref (message);
01644         return FALSE;
01645     }
01646     if (reply == NULL) {
01647         dbus_message_unref (message);
01648         return FALSE;
01649     }
01650     /* now analyse reply */
01651     dbus_message_iter_init (reply, &iter);
01652     if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_BOOLEAN) {
01653         fprintf (stderr,
01654              "%s %d : expected a bool in reply to DeviceMatches\n",
01655              __FILE__, __LINE__);
01656         dbus_message_unref (message);
01657         dbus_message_unref (reply);
01658         return FALSE;
01659     }
01660 
01661     value = dbus_message_iter_get_boolean (&iter);
01662 
01663     dbus_message_unref (message);
01664     dbus_message_unref (reply);
01665     return value;
01666 }
01667 
01672 void
01673 hal_device_print (LibHalContext *ctx, const char *udi)
01674 {
01675     int type;
01676     char *key;
01677     LibHalPropertySet *pset;
01678     LibHalPropertySetIterator i;
01679 
01680     printf ("device_id = %s\n", udi);
01681 
01682     pset = hal_device_get_all_properties (ctx, udi);
01683 
01684     for (hal_psi_init (&i, pset); hal_psi_has_more (&i);
01685          hal_psi_next (&i)) {
01686         type = hal_psi_get_type (&i);
01687         key = hal_psi_get_key (&i);
01688         switch (type) {
01689         case DBUS_TYPE_STRING:
01690             printf ("    %s = %s (string)\n", key,
01691                 hal_psi_get_string (&i));
01692             break;
01693         case DBUS_TYPE_INT32:
01694             printf ("    %s = %d = 0x%x (int)\n", key,
01695                 hal_psi_get_int (&i),
01696                 hal_psi_get_int (&i));
01697             break;
01698         case DBUS_TYPE_BOOLEAN:
01699             printf ("    %s = %s (bool)\n", key,
01700                 (hal_psi_get_bool (&i) ? "true" :
01701                  "false"));
01702             break;
01703         case DBUS_TYPE_DOUBLE:
01704             printf ("    %s = %g (double)\n", key,
01705                 hal_psi_get_double (&i));
01706             break;
01707         default:
01708             printf ("    *** unknown type for key %s\n", key);
01709             break;
01710         }
01711     }
01712     hal_free_property_set (pset);
01713 }
01714 
01724 char **
01725 hal_manager_find_device_string_match (LibHalContext *ctx, 
01726                       const char *key,
01727                       const char *value, int *num_devices)
01728 {
01729     int i;
01730     DBusError error;
01731     DBusMessage *message;
01732     DBusMessage *reply;
01733     DBusMessageIter iter;
01734     char **device_names;
01735     char **hal_device_names;
01736 
01737     message = dbus_message_new_method_call ("org.freedesktop.Hal",
01738                         "/org/freedesktop/Hal/Manager",
01739                         "org.freedesktop.Hal.Manager",
01740                         "FindDeviceStringMatch");
01741     if (message == NULL) {
01742         fprintf (stderr,
01743              "%s %d : Couldn't allocate D-BUS message\n",
01744              __FILE__, __LINE__);
01745         return NULL;
01746     }
01747 
01748     dbus_message_iter_init (message, &iter);
01749     dbus_message_iter_append_string (&iter, key);
01750     dbus_message_iter_append_string (&iter, value);
01751 
01752     dbus_error_init (&error);
01753     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01754                                message, -1,
01755                                &error);
01756     if (dbus_error_is_set (&error)) {
01757         fprintf (stderr, "%s %d : Error sending msg: %s\n",
01758              __FILE__, __LINE__, error.message);
01759         dbus_message_unref (message);
01760         return NULL;
01761     }
01762     if (reply == NULL) {
01763         dbus_message_unref (message);
01764         return NULL;
01765     }
01766     /* now analyse reply */
01767     dbus_message_iter_init (reply, &iter);
01768     if (!dbus_message_iter_get_string_array (&iter,
01769                          &device_names,
01770                          num_devices)) {
01771         fprintf (stderr, "%s %d : wrong reply from hald\n",
01772              __FILE__, __LINE__);
01773         return NULL;
01774     }
01775 
01776     dbus_message_unref (message);
01777     dbus_message_unref (reply);
01778 
01779     /* Have to convert from dbus string array to hal string array 
01780      * since we can't poke at the dbus string array for the reason
01781      * that d-bus use their own memory allocation scheme
01782      */
01783     hal_device_names = malloc (sizeof (char *) * ((*num_devices) + 1));
01784     if (hal_device_names == NULL)
01785         return NULL;
01788     for (i = 0; i < (*num_devices); i++) {
01789         hal_device_names[i] = strdup (device_names[i]);
01790         if (hal_device_names[i] == NULL)
01791             return NULL;
01793     }
01794     hal_device_names[i] = NULL;
01795 
01796     dbus_free_string_array (device_names);
01797 
01798     return hal_device_names;
01799 }
01800 
01801 
01809 dbus_bool_t
01810 hal_device_add_capability (LibHalContext *ctx, 
01811                const char *udi, const char *capability)
01812 {
01813     DBusError error;
01814     DBusMessage *message;
01815     DBusMessage *reply;
01816     DBusMessageIter iter;
01817 
01818     message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
01819                         "org.freedesktop.Hal.Device",
01820                         "AddCapability");
01821     if (message == NULL) {
01822         fprintf (stderr,
01823              "%s %d : Couldn't allocate D-BUS message\n",
01824              __FILE__, __LINE__);
01825         return FALSE;
01826     }
01827 
01828     dbus_message_iter_init (message, &iter);
01829     dbus_message_iter_append_string (&iter, capability);
01830 
01831     dbus_error_init (&error);
01832     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01833                                message, -1,
01834                                &error);
01835     if (dbus_error_is_set (&error)) {
01836         fprintf (stderr, "%s %d: %s raised\n\"%s\"\n\n", __FILE__,
01837              __LINE__, error.name, error.message);
01838         dbus_message_unref (message);
01839         return FALSE;
01840     }
01841 
01842     if (reply == NULL) {
01843         dbus_message_unref (message);
01844         return FALSE;
01845     }
01846 
01847     dbus_message_unref (reply);
01848     dbus_message_unref (message);
01849     return TRUE;
01850 }
01851 
01860 dbus_bool_t
01861 hal_device_query_capability (LibHalContext *ctx, 
01862                  const char *udi, const char *capability)
01863 {
01864     char *caps;
01865 
01866     caps = hal_device_get_property_string (ctx, udi, "info.capabilities");
01867 
01868     if (caps != NULL)
01869         if (strstr (caps, capability) != NULL)
01870             return TRUE;
01871 
01872     return FALSE;
01873 }
01874 
01882 char **
01883 hal_find_device_by_capability (LibHalContext *ctx, 
01884                    const char *capability, int *num_devices)
01885 {
01886     int i;
01887     DBusError error;
01888     DBusMessage *message;
01889     DBusMessage *reply;
01890     DBusMessageIter iter;
01891     char **device_names;
01892     char **hal_device_names;
01893 
01894     message = dbus_message_new_method_call ("org.freedesktop.Hal",
01895                         "/org/freedesktop/Hal/Manager",
01896                         "org.freedesktop.Hal.Manager",
01897                         "FindDeviceByCapability");
01898     if (message == NULL) {
01899         fprintf (stderr,
01900              "%s %d : Couldn't allocate D-BUS message\n",
01901              __FILE__, __LINE__);
01902         return NULL;
01903     }
01904 
01905     dbus_message_iter_init (message, &iter);
01906     dbus_message_iter_append_string (&iter, capability);
01907 
01908     dbus_error_init (&error);
01909     reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01910                                message, -1,
01911                                &error);
01912     if (dbus_error_is_set (&error)) {
01913         fprintf (stderr, "%s %d : Error sending msg: %s\n",
01914              __FILE__, __LINE__, error.message);
01915         dbus_message_unref (message);
01916         return NULL;
01917     }
01918     if (reply == NULL) {
01919         dbus_message_unref (message);
01920         return NULL;
01921     }
01922     /* now analyse reply */
01923     dbus_message_iter_init (reply, &iter);
01924     if (!dbus_message_iter_get_string_array (&iter,
01925                          &device_names,
01926                          num_devices)) {
01927         fprintf (stderr, "%s %d : wrong reply from hald\n",
01928              __FILE__, __LINE__);
01929         return NULL;
01930     }
01931 
01932     dbus_message_unref (message);
01933     dbus_message_unref (reply);
01934 
01935     /* Have to convert from dbus string array to hal string array 
01936      * since we can't poke at the dbus string array for the reason
01937      * that d-bus use their own memory allocation scheme
01938      */
01939     hal_device_names = malloc (sizeof (char *) * ((*num_devices) + 1));
01940     if (hal_device_names == NULL)
01941         return NULL;
01944     for (i = 0; i < (*num_devices); i++) {
01945         hal_device_names[i] = strdup (device_names[i]);
01946         if (hal_device_names[i] == NULL)
01947             return NULL;
01949     }
01950     hal_device_names[i] = NULL;
01951 
01952     dbus_free_string_array (device_names);
01953 
01954     return hal_device_names;
01955 }
01956 
01963 int
01964 hal_device_property_watch_all (LibHalContext *ctx)
01965 {
01966     DBusError error;
01967 
01968     dbus_error_init (&error);
01969 
01970     dbus_bus_add_match (ctx->connection,
01971                 "type='signal',"
01972                 "interface='org.freedesktop.Hal.Device',"
01973                 "sender='org.freedesktop.Hal'", &error);
01974     if (dbus_error_is_set (&error)) {
01975         fprintf (stderr, "%s %d : Error subscribing to signals, "
01976              "error=%s\r\n",
01977              __FILE__, __LINE__, error.message);
01978         return 1;
01979     }
01980     return 0;
01981 }
01982 
01983 
01994 int
01995 hal_device_add_property_watch (LibHalContext *ctx, const char *udi)
01996 {
01997     char buf[512];
01998     DBusError error;
01999 
02000     dbus_error_init (&error);
02001 
02002     snprintf (buf, 512,
02003           "type='signal',"
02004           "interface='org.freedesktop.Hal.Device',"
02005           "sender='org.freedesktop.Hal'," "path=%s", udi);
02006 
02007     dbus_bus_add_match (ctx->connection, buf, &error);
02008     if (dbus_error_is_set (&error)) {
02009         fprintf (stderr, "%s %d : Error subscribing to signals, "
02010              "error=%s\r\n",
02011              __FILE__, __LINE__, error.message);
02012         return 1;
02013     }
02014     return 0;
02015 }
02016 
02017 
02024 int
02025 hal_device_remove_property_watch (LibHalContext *ctx, const char *udi)
02026 {
02027     char buf[512];
02028     DBusError error;
02029 
02030     dbus_error_init (&error);
02031 
02032     snprintf (buf, 512,
02033           "type='signal',"
02034           "interface='org.freedesktop.Hal.Device',"
02035           "sender='org.freedesktop.Hal'," "path=%s", udi);
02036 
02037     dbus_bus_remove_match (ctx->connection, buf, &error);
02038     if (dbus_error_is_set (&error)) {
02039         fprintf (stderr, "%s %d : Error unsubscribing to signals, "
02040              "error=%s\r\n",
02041              __FILE__, __LINE__, error.message);
02042         return 1;
02043     }
02044     return 0;
02045 }
02046 
02047 

Generated on Sat Apr 24 19:57:45 2004 for HAL by doxygen 1.3.6-20040222