00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
00037 #ifdef ENABLE_NLS
00038 # include <libintl.h>
00039 # define _(String) dgettext (GETTEXT_PACKAGE, String)
00040 # ifdef gettext_noop
00041 # define N_(String) gettext_noop (String)
00042 # else
00043 # define N_(String) (String)
00044 # endif
00045 #else
00046
00047 # define textdomain(String) (String)
00048 # define gettext(String) (String)
00049 # define dgettext(Domain,Message) (Message)
00050 # define dcgettext(Domain,Message,Type) (Message)
00051 # define bindtextdomain(Domain,Directory) (Domain)
00052 # define _(String)
00053 # define N_(String) (String)
00054 #endif
00055
00068 void
00069 hal_free_string_array (char **str_array)
00070 {
00071 if (str_array != NULL) {
00072 int i;
00073
00074 for (i = 0; str_array[i] != NULL; i++) {
00075 free (str_array[i]);
00076 }
00077 free (str_array);
00078 }
00079 }
00080
00085 void
00086 hal_free_string (char *str)
00087 {
00089 free (str);
00090 }
00091
00092
00094 struct LibHalPropertySet_s {
00095 unsigned int num_properties;
00096 LibHalProperty *properties_head;
00099 };
00100
00102 struct LibHalProperty_s {
00103 int type;
00104 char *key;
00107 union {
00108 char *str_value;
00109 dbus_int32_t int_value;
00111 dbus_uint64_t uint64_value;
00113 double double_value;
00114 dbus_bool_t bool_value;
00116 };
00117
00118 LibHalProperty *next;
00120 };
00121
00123 struct LibHalContext_s {
00124 DBusConnection *connection;
00125 dbus_bool_t is_initialized;
00126 dbus_bool_t is_shutdown;
00127 dbus_bool_t cache_enabled;
00128 const LibHalFunctions *functions;
00129 void *user_data;
00130 };
00131
00137 void
00138 hal_ctx_set_user_data(LibHalContext *ctx, void *user_data)
00139 {
00140 ctx->user_data = user_data;
00141 }
00142
00149 void*
00150 hal_ctx_get_user_data(LibHalContext *ctx)
00151 {
00152 return ctx->user_data;
00153 }
00154
00155
00163 LibHalPropertySet *
00164 hal_device_get_all_properties (LibHalContext *ctx, const char *udi)
00165 {
00166 DBusError error;
00167 DBusMessage *message;
00168 DBusMessage *reply;
00169 DBusMessageIter iter;
00170 DBusMessageIter dict_iter;
00171 LibHalPropertySet *result;
00172 LibHalProperty **pn;
00173
00174 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
00175 "org.freedesktop.Hal.Device",
00176 "GetAllProperties");
00177 if (message == NULL) {
00178 fprintf (stderr,
00179 "%s %d : Couldn't allocate D-BUS message\n",
00180 __FILE__, __LINE__);
00181 return NULL;
00182 }
00183
00184 dbus_error_init (&error);
00185 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
00186 message, -1,
00187 &error);
00188 if (dbus_error_is_set (&error)) {
00189 fprintf (stderr, "%s %d: %s raised\n\"%s\"\n\n", __FILE__,
00190 __LINE__, error.name, error.message);
00191 dbus_message_unref (message);
00192 return NULL;
00193 }
00194
00195 if (reply == NULL) {
00196 dbus_message_unref (message);
00197 return NULL;
00198 }
00199
00200 dbus_message_iter_init (reply, &iter);
00201
00202 result = malloc (sizeof (LibHalPropertySet));
00203 if (result == NULL) {
00204 fprintf (stderr, "%s %d : error allocating memory\n",
00205 __FILE__, __LINE__);
00206 dbus_message_unref (message);
00207 dbus_message_unref (reply);
00208 return NULL;
00209 }
00210
00211
00212
00213
00214
00216
00217
00218
00219
00220 pn = &result->properties_head;
00221 result->num_properties = 0;
00222
00223 dbus_message_iter_init_dict_iterator (&iter, &dict_iter);
00224
00225 do {
00226 char *dbus_str;
00227 LibHalProperty *p;
00228
00229 p = malloc (sizeof (LibHalProperty));
00230 if (p == NULL) {
00231 fprintf (stderr,
00232 "%s %d : error allocating memory\n",
00233 __FILE__, __LINE__);
00235 return NULL;
00236 }
00237
00238 *pn = p;
00239 pn = &p->next;
00240 p->next = NULL;
00241 result->num_properties++;
00242
00243 dbus_str = dbus_message_iter_get_dict_key (&dict_iter);
00244 p->key =
00245 (char *) ((dbus_str != NULL) ? strdup (dbus_str) :
00246 NULL);
00247 if (p->key == NULL) {
00248 fprintf (stderr,
00249 "%s %d : error allocating memory\n",
00250 __FILE__, __LINE__);
00252 return NULL;
00253 }
00254 dbus_free (dbus_str);
00255
00256 p->type = dbus_message_iter_get_arg_type (&dict_iter);
00257
00258 switch (p->type) {
00259 case DBUS_TYPE_STRING:
00260 dbus_str =
00261 dbus_message_iter_get_string (&dict_iter);
00262 p->str_value =
00263 (char *) ((dbus_str != NULL) ?
00264 strdup (dbus_str) : NULL);
00265 if (p->str_value == NULL) {
00266 fprintf (stderr,
00267 "%s %d : error allocating memory\n",
00268 __FILE__, __LINE__);
00270 return NULL;
00271 }
00272 dbus_free (dbus_str);
00273 break;
00274 case DBUS_TYPE_INT32:
00275 p->int_value =
00276 dbus_message_iter_get_int32 (&dict_iter);
00277 break;
00278 case DBUS_TYPE_UINT64:
00279 p->uint64_value =
00280 dbus_message_iter_get_uint64 (&dict_iter);
00281 break;
00282 case DBUS_TYPE_DOUBLE:
00283 p->double_value =
00284 dbus_message_iter_get_double (&dict_iter);
00285 break;
00286 case DBUS_TYPE_BOOLEAN:
00287 p->bool_value =
00288 dbus_message_iter_get_boolean (&dict_iter);
00289 break;
00290
00291 default:
00293 break;
00294 }
00295
00296 }
00297 while (dbus_message_iter_has_next (&dict_iter) &&
00298 dbus_message_iter_next (&dict_iter));
00299
00300 dbus_message_unref (message);
00301 dbus_message_unref (reply);
00302
00303 return result;
00304 }
00305
00310 void
00311 hal_free_property_set (LibHalPropertySet * set)
00312 {
00313 LibHalProperty *p;
00314 LibHalProperty *q;
00315
00316 if (set == NULL)
00317 return;
00318
00319 for (p = set->properties_head; p != NULL; p = q) {
00320 free (p->key);
00321 if (p->type == DBUS_TYPE_STRING)
00322 free (p->str_value);
00323 q = p->next;
00324 free (p);
00325 }
00326 free (set);
00327 }
00328
00334 void
00335 hal_psi_init (LibHalPropertySetIterator * iter, LibHalPropertySet * set)
00336 {
00337 iter->set = set;
00338 iter->index = 0;
00339 iter->cur_prop = set->properties_head;
00340 }
00341
00347 dbus_bool_t
00348 hal_psi_has_more (LibHalPropertySetIterator * iter)
00349 {
00350 return iter->index < iter->set->num_properties;
00351 }
00352
00357 void
00358 hal_psi_next (LibHalPropertySetIterator * iter)
00359 {
00360 iter->index++;
00361 iter->cur_prop = iter->cur_prop->next;
00362 }
00363
00370 int
00371 hal_psi_get_type (LibHalPropertySetIterator * iter)
00372 {
00373 return iter->cur_prop->type;
00374 }
00375
00384 char *
00385 hal_psi_get_key (LibHalPropertySetIterator * iter)
00386 {
00387 return iter->cur_prop->key;
00388 }
00389
00398 char *
00399 hal_psi_get_string (LibHalPropertySetIterator * iter)
00400 {
00401 return iter->cur_prop->str_value;
00402 }
00403
00409 dbus_int32_t
00410 hal_psi_get_int (LibHalPropertySetIterator * iter)
00411 {
00412 return iter->cur_prop->int_value;
00413 }
00414
00420 dbus_uint64_t
00421 hal_psi_get_uint64 (LibHalPropertySetIterator * iter)
00422 {
00423 return iter->cur_prop->uint64_value;
00424 }
00425
00431 double
00432 hal_psi_get_double (LibHalPropertySetIterator * iter)
00433 {
00434 return iter->cur_prop->double_value;
00435 }
00436
00442 dbus_bool_t
00443 hal_psi_get_bool (LibHalPropertySetIterator * iter)
00444 {
00445 return iter->cur_prop->bool_value;
00446 }
00447
00448
00449 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00450 static DBusHandlerResult
00451 filter_func (DBusConnection * connection,
00452 DBusMessage * message, void *user_data)
00453 {
00454 const char *object_path;
00455 DBusError error;
00456 LibHalContext *ctx = (LibHalContext *) user_data;
00457
00458 if (ctx->is_shutdown)
00459 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
00460
00461 dbus_error_init (&error);
00462
00463 object_path = dbus_message_get_path (message);
00464
00465
00466
00467 if (dbus_message_is_signal (message, "org.freedesktop.Hal.Manager",
00468 "DeviceAdded")) {
00469 char *udi;
00470 if (dbus_message_get_args (message, &error,
00471 DBUS_TYPE_STRING, &udi,
00472 DBUS_TYPE_INVALID)) {
00473 if (ctx->functions->device_added != NULL) {
00474 ctx->functions->device_added (ctx, udi);
00475 }
00476 dbus_free (udi);
00477 }
00478 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
00479 } else
00480 if (dbus_message_is_signal
00481 (message, "org.freedesktop.Hal.Manager",
00482 "DeviceRemoved")) {
00483 char *udi;
00484 if (dbus_message_get_args (message, &error,
00485 DBUS_TYPE_STRING, &udi,
00486 DBUS_TYPE_INVALID)) {
00487 if (ctx->functions->device_removed != NULL) {
00488 ctx->functions->device_removed (ctx, udi);
00489 }
00490 dbus_free (udi);
00491 }
00492 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
00493 } else
00494 if (dbus_message_is_signal
00495 (message, "org.freedesktop.Hal.Manager",
00496 "NewCapability")) {
00497 char *udi;
00498 char *capability;
00499 if (dbus_message_get_args (message, &error,
00500 DBUS_TYPE_STRING, &udi,
00501 DBUS_TYPE_STRING, &capability,
00502 DBUS_TYPE_INVALID)) {
00503 if (ctx->functions->device_new_capability != NULL) {
00504 ctx->functions->device_new_capability (ctx,
00505 udi,
00506 capability);
00507 }
00508 dbus_free (udi);
00509 dbus_free (capability);
00510 }
00511 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
00512 } else
00513 if (dbus_message_is_signal
00514 (message, "org.freedesktop.Hal.Device", "Condition")) {
00515 if (ctx->functions->device_condition != NULL) {
00516 DBusMessageIter iter;
00517 char *condition_name;
00518
00519 dbus_message_iter_init (message, &iter);
00520 condition_name =
00521 dbus_message_iter_get_string (&iter);
00522
00523 ctx->functions->device_condition (ctx,
00524 object_path,
00525 condition_name,
00526 message);
00527
00528 dbus_free (condition_name);
00529 }
00530 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
00531 } else
00532 if (dbus_message_is_signal
00533 (message, "org.freedesktop.Hal.Device",
00534 "PropertyModified")) {
00535 if (ctx->functions->device_property_modified != NULL) {
00536 int i;
00537 char *key;
00538 dbus_bool_t removed, added;
00539 int num_modifications;
00540 DBusMessageIter iter;
00541
00542 dbus_message_iter_init (message, &iter);
00543 num_modifications =
00544 dbus_message_iter_get_int32 (&iter);
00545 dbus_message_iter_next (&iter);
00546
00547
00548 for (i = 0; i < num_modifications; i++) {
00549
00550 key = dbus_message_iter_get_string (&iter);
00551 dbus_message_iter_next (&iter);
00552 removed =
00553 dbus_message_iter_get_boolean (&iter);
00554 dbus_message_iter_next (&iter);
00555 added =
00556 dbus_message_iter_get_boolean (&iter);
00557 dbus_message_iter_next (&iter);
00558
00559 ctx->functions->
00560 device_property_modified (ctx,
00561 object_path,
00562 key, removed,
00563 added);
00564
00565 dbus_free (key);
00566 }
00567
00568 }
00569 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
00570 }
00571
00572 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
00573 }
00574
00575 static LibHalFunctions hal_null_functions = {
00576 NULL ,
00577 NULL ,
00578 NULL ,
00579 NULL ,
00580 NULL ,
00581 NULL ,
00582 NULL
00583 };
00584 #endif
00585
00586
00587 static dbus_bool_t hal_already_initialized_once = FALSE;
00588
00607 LibHalContext*
00608 hal_initialize (const LibHalFunctions * cb_functions,
00609 dbus_bool_t use_cache)
00610 {
00611 DBusError error;
00612 LibHalContext *ctx;
00613
00614 if (!hal_already_initialized_once) {
00615 bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
00616 bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
00617
00618 hal_already_initialized_once = TRUE;
00619 }
00620
00621 ctx = malloc (sizeof (LibHalContext));
00622 if (ctx == NULL) {
00623 fprintf (stderr, "%s %d : Cannot allocated %d bytes!\n",
00624 __FILE__, __LINE__, sizeof (LibHalContext));
00625 return NULL;
00626 }
00627
00628 ctx->is_initialized = FALSE;
00629 ctx->is_shutdown = FALSE;
00630
00631 ctx->cache_enabled = use_cache;
00632
00633 ctx->functions = cb_functions;
00634
00635 if (ctx->functions == NULL)
00636 ctx->functions = &hal_null_functions;
00637
00638
00639 dbus_error_init (&error);
00640 ctx->connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
00641 if (ctx->connection == NULL) {
00642 fprintf (stderr,
00643 "%s %d : Error connecting to system bus: %s\n",
00644 __FILE__, __LINE__, error.message);
00645 dbus_error_free (&error);
00646 return NULL;
00647 }
00648
00649 if (ctx->functions->main_loop_integration != NULL) {
00650
00651 ctx->functions->main_loop_integration (ctx, ctx->connection);
00652 }
00653
00654 if (!dbus_connection_add_filter
00655 (ctx->connection, filter_func, ctx, NULL)) {
00656 fprintf (stderr,
00657 "%s %d : Error creating connection handler\r\n",
00658 __FILE__, __LINE__);
00660 return NULL;
00661 }
00662
00663 dbus_bus_add_match (ctx->connection,
00664 "type='signal',"
00665 "interface='org.freedesktop.Hal.Manager',"
00666 "sender='org.freedesktop.Hal',"
00667 "path='/org/freedesktop/Hal/Manager'", &error);
00668 if (dbus_error_is_set (&error)) {
00669 fprintf (stderr, "%s %d : Error subscribing to signals, "
00670 "error=%s\r\n",
00671 __FILE__, __LINE__, error.message);
00673 return NULL;
00674 }
00675
00676 ctx->is_initialized = TRUE;
00677 return ctx;
00678 }
00679
00686 int
00687 hal_shutdown (LibHalContext *ctx)
00688 {
00689 DBusError error;
00690
00691 if (!ctx->is_initialized)
00692 return 1;
00693
00694
00695
00696 dbus_error_init (&error);
00697 dbus_bus_remove_match (ctx->connection,
00698 "type='signal',"
00699 "interface='org.freedesktop.Hal.Manager',"
00700 "sender='org.freedesktop.Hal',"
00701 "path='/org/freedesktop/Hal/Manager'", &error);
00702 if (dbus_error_is_set (&error)) {
00703 fprintf (stderr, "%s %d : Error removing match rule, error=%s\r\n",
00704 __FILE__, __LINE__, error.message);
00705 }
00706
00707
00708
00709
00710 ctx->is_shutdown = TRUE;
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725 return 0;
00726 }
00727
00737 char **
00738 hal_get_all_devices (LibHalContext *ctx, int *num_devices)
00739 {
00740 int i;
00741 DBusError error;
00742 DBusMessage *message;
00743 DBusMessage *reply;
00744 DBusMessageIter iter;
00745 char **device_names;
00746 char **hal_device_names;
00747
00748 *num_devices = 0;
00749
00750 message = dbus_message_new_method_call ("org.freedesktop.Hal",
00751 "/org/freedesktop/Hal/Manager",
00752 "org.freedesktop.Hal.Manager",
00753 "GetAllDevices");
00754 if (message == NULL) {
00755 fprintf (stderr,
00756 "%s %d : Couldn't allocate D-BUS message\n",
00757 __FILE__, __LINE__);
00758 return NULL;
00759 }
00760
00761 dbus_error_init (&error);
00762 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
00763 message, -1,
00764 &error);
00765 if (dbus_error_is_set (&error)) {
00766 fprintf (stderr, "%s %d : %s raised\n\"%s\"\n\n", __FILE__,
00767 __LINE__, error.name, error.message);
00768 dbus_message_unref (message);
00769 return NULL;
00770 }
00771
00772 if (reply == NULL) {
00773 dbus_message_unref (message);
00774 return NULL;
00775 }
00776
00777
00778 dbus_message_iter_init (reply, &iter);
00779 if (!dbus_message_iter_get_string_array (&iter,
00780 &device_names,
00781 num_devices)) {
00782 fprintf (stderr, "%s %d : wrong reply from hald\n",
00783 __FILE__, __LINE__);
00784 return NULL;
00785 }
00786
00787 dbus_message_unref (reply);
00788 dbus_message_unref (message);
00789
00790
00791
00792
00793
00794 hal_device_names = malloc (sizeof (char *) * ((*num_devices) + 1));
00795 if (hal_device_names == NULL)
00796 return NULL;
00799 for (i = 0; i < (*num_devices); i++) {
00800 hal_device_names[i] = strdup (device_names[i]);
00801 if (hal_device_names[i] == NULL) {
00802 fprintf (stderr,
00803 "%s %d : error allocating memory\n",
00804 __FILE__, __LINE__);
00806 return NULL;
00807 }
00808 }
00809 hal_device_names[i] = NULL;
00810
00811 dbus_free_string_array (device_names);
00812
00813 return hal_device_names;
00814 }
00815
00825 int
00826 hal_device_get_property_type (LibHalContext *ctx,
00827 const char *udi, const char *key)
00828 {
00829 DBusError error;
00830 DBusMessage *message;
00831 DBusMessage *reply;
00832 DBusMessageIter iter;
00833 int type;
00834
00835 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
00836 "org.freedesktop.Hal.Device",
00837 "GetPropertyType");
00838 if (message == NULL) {
00839 fprintf (stderr,
00840 "%s %d : Couldn't allocate D-BUS message\n",
00841 __FILE__, __LINE__);
00842 return DBUS_TYPE_NIL;
00843 }
00844
00845 dbus_message_iter_init (message, &iter);
00846 dbus_message_iter_append_string (&iter, key);
00847 dbus_error_init (&error);
00848 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
00849 message, -1,
00850 &error);
00851 if (dbus_error_is_set (&error)) {
00852 fprintf (stderr, "%s %d : %s raised\n\"%s\"\n\n", __FILE__,
00853 __LINE__, error.name, error.message);
00854 dbus_message_unref (message);
00855 return DBUS_TYPE_NIL;
00856 }
00857 if (reply == NULL) {
00858 dbus_message_unref (message);
00859 return DBUS_TYPE_NIL;
00860 }
00861
00862 dbus_message_iter_init (reply, &iter);
00863 type = dbus_message_iter_get_int32 (&iter);
00864
00865 dbus_message_unref (message);
00866 dbus_message_unref (reply);
00867
00868 return type;
00869 }
00870
00882 char *
00883 hal_device_get_property_string (LibHalContext *ctx,
00884 const char *udi, const char *key)
00885 {
00886 DBusError error;
00887 DBusMessage *message;
00888 DBusMessage *reply;
00889 DBusMessageIter iter;
00890 char *value;
00891 char *dbus_str;
00892
00893 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
00894 "org.freedesktop.Hal.Device",
00895 "GetPropertyString");
00896 if (message == NULL) {
00897 fprintf (stderr,
00898 "%s %d : Couldn't allocate D-BUS message\n",
00899 __FILE__, __LINE__);
00900 return NULL;
00901 }
00902
00903 dbus_message_iter_init (message, &iter);
00904 dbus_message_iter_append_string (&iter, key);
00905 dbus_error_init (&error);
00906 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
00907 message, -1,
00908 &error);
00909 if (dbus_error_is_set (&error)) {
00910 fprintf (stderr, "%s %d : Error sending msg: %s\n",
00911 __FILE__, __LINE__, error.message);
00912 dbus_message_unref (message);
00913 return NULL;
00914 }
00915 if (reply == NULL) {
00916 dbus_message_unref (message);
00917 return NULL;
00918 }
00919
00920 dbus_message_iter_init (reply, &iter);
00921
00922
00923 if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_NIL) {
00924 fprintf (stderr,
00925 "%s %d : property '%s' for device '%s' does not "
00926 "exist\n", __FILE__, __LINE__, key, udi);
00927 dbus_message_unref (message);
00928 dbus_message_unref (reply);
00929 return NULL;
00930 } else if (dbus_message_iter_get_arg_type (&iter) !=
00931 DBUS_TYPE_STRING) {
00932 fprintf (stderr,
00933 "%s %d : property '%s' for device '%s' is not "
00934 "of type string\n", __FILE__, __LINE__, key, udi);
00935 dbus_message_unref (message);
00936 dbus_message_unref (reply);
00937 return NULL;
00938 }
00939
00940 dbus_str = dbus_message_iter_get_string (&iter);
00941 value = (char *) ((dbus_str != NULL) ? strdup (dbus_str) : NULL);
00942 if (value == NULL) {
00943 fprintf (stderr, "%s %d : error allocating memory\n",
00944 __FILE__, __LINE__);
00946 return NULL;
00947 }
00948 dbus_free (dbus_str);
00949
00950 dbus_message_unref (message);
00951 dbus_message_unref (reply);
00952 return value;
00953 }
00954
00962 dbus_int32_t
00963 hal_device_get_property_int (LibHalContext *ctx,
00964 const char *udi, const char *key)
00965 {
00966 DBusError error;
00967 DBusMessage *message;
00968 DBusMessage *reply;
00969 DBusMessageIter iter;
00970 dbus_int32_t value;
00971
00972 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
00973 "org.freedesktop.Hal.Device",
00974 "GetPropertyInteger");
00975 if (message == NULL) {
00976 fprintf (stderr,
00977 "%s %d : Couldn't allocate D-BUS message\n",
00978 __FILE__, __LINE__);
00979 return -1;
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 (ctx->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 -1;
00993 }
00994 if (reply == NULL) {
00995 dbus_message_unref (message);
00996 return -1;
00997 }
00998
00999 dbus_message_iter_init (reply, &iter);
01000
01001
01002 if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_NIL) {
01003
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 -1;
01010 } else if (dbus_message_iter_get_arg_type (&iter) !=
01011 DBUS_TYPE_INT32) {
01012 fprintf (stderr,
01013 "%s %d : property '%s' for device '%s' is not "
01014 "of type integer\n", __FILE__, __LINE__, key,
01015 udi);
01016 dbus_message_unref (message);
01017 dbus_message_unref (reply);
01018 return -1;
01019 }
01020 value = dbus_message_iter_get_int32 (&iter);
01021
01022 dbus_message_unref (message);
01023 dbus_message_unref (reply);
01024 return value;
01025 }
01026
01034 dbus_uint64_t
01035 hal_device_get_property_uint64 (LibHalContext *ctx,
01036 const char *udi, const char *key)
01037 {
01038 DBusError error;
01039 DBusMessage *message;
01040 DBusMessage *reply;
01041 DBusMessageIter iter;
01042 dbus_uint64_t value;
01043
01044 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
01045 "org.freedesktop.Hal.Device",
01046 "GetPropertyInteger");
01047 if (message == NULL) {
01048 fprintf (stderr,
01049 "%s %d : Couldn't allocate D-BUS message\n",
01050 __FILE__, __LINE__);
01051 return -1;
01052 }
01053
01054 dbus_message_iter_init (message, &iter);
01055 dbus_message_iter_append_string (&iter, key);
01056 dbus_error_init (&error);
01057 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01058 message, -1,
01059 &error);
01060 if (dbus_error_is_set (&error)) {
01061 fprintf (stderr, "%s %d : Error sending msg: %s\n",
01062 __FILE__, __LINE__, error.message);
01063 dbus_message_unref (message);
01064 return -1;
01065 }
01066 if (reply == NULL) {
01067 dbus_message_unref (message);
01068 return -1;
01069 }
01070
01071 dbus_message_iter_init (reply, &iter);
01072
01073
01074 if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_NIL) {
01075
01076 fprintf (stderr,
01077 "%s %d : property '%s' for device '%s' does not "
01078 "exist\n", __FILE__, __LINE__, key, udi);
01079 dbus_message_unref (message);
01080 dbus_message_unref (reply);
01081 return -1;
01082 } else if (dbus_message_iter_get_arg_type (&iter) !=
01083 DBUS_TYPE_UINT64) {
01084 fprintf (stderr,
01085 "%s %d : property '%s' for device '%s' is not "
01086 "of type integer\n", __FILE__, __LINE__, key,
01087 udi);
01088 dbus_message_unref (message);
01089 dbus_message_unref (reply);
01090 return -1;
01091 }
01092 value = dbus_message_iter_get_uint64 (&iter);
01093
01094 dbus_message_unref (message);
01095 dbus_message_unref (reply);
01096 return value;
01097 }
01098
01106 double
01107 hal_device_get_property_double (LibHalContext *ctx,
01108 const char *udi, const char *key)
01109 {
01110 DBusError error;
01111 DBusMessage *message;
01112 DBusMessage *reply;
01113 DBusMessageIter iter;
01114 double value;
01115
01116 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
01117 "org.freedesktop.Hal.Device",
01118 "GetPropertyDouble");
01119 if (message == NULL) {
01120 fprintf (stderr,
01121 "%s %d : Couldn't allocate D-BUS message\n",
01122 __FILE__, __LINE__);
01123 return -1.0f;
01124 }
01125
01126 dbus_message_iter_init (message, &iter);
01127 dbus_message_iter_append_string (&iter, key);
01128 dbus_error_init (&error);
01129 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01130 message, -1,
01131 &error);
01132 if (dbus_error_is_set (&error)) {
01133 fprintf (stderr, "%s %d : Error sending msg: %s\n",
01134 __FILE__, __LINE__, error.message);
01135 dbus_message_unref (message);
01136 return -1.0f;
01137 }
01138 if (reply == NULL) {
01139 dbus_message_unref (message);
01140 return -1.0f;
01141 }
01142
01143 dbus_message_iter_init (reply, &iter);
01144
01145
01146 if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_NIL) {
01147
01148 fprintf (stderr,
01149 "%s %d : property '%s' for device '%s' does not "
01150 "exist\n", __FILE__, __LINE__, key, udi);
01151 dbus_message_unref (message);
01152 dbus_message_unref (reply);
01153 return -1.0f;
01154 } else if (dbus_message_iter_get_arg_type (&iter) !=
01155 DBUS_TYPE_DOUBLE) {
01156 fprintf (stderr,
01157 "%s %d : property '%s' for device '%s' is not "
01158 "of type double\n", __FILE__, __LINE__, key, udi);
01159 dbus_message_unref (message);
01160 dbus_message_unref (reply);
01161 return -1.0f;
01162 }
01163 value = dbus_message_iter_get_double (&iter);
01164
01165 dbus_message_unref (message);
01166 dbus_message_unref (reply);
01167 return (double) value;
01168 }
01169
01177 dbus_bool_t
01178 hal_device_get_property_bool (LibHalContext *ctx,
01179 const char *udi, const char *key)
01180 {
01181 DBusError error;
01182 DBusMessage *message;
01183 DBusMessage *reply;
01184 DBusMessageIter iter;
01185 double value;
01186
01187 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
01188 "org.freedesktop.Hal.Device",
01189 "GetPropertyBoolean");
01190 if (message == NULL) {
01191 fprintf (stderr,
01192 "%s %d : Couldn't allocate D-BUS message\n",
01193 __FILE__, __LINE__);
01194 return FALSE;
01195 }
01196
01197 dbus_message_iter_init (message, &iter);
01198 dbus_message_iter_append_string (&iter, key);
01199 dbus_error_init (&error);
01200 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01201 message, -1,
01202 &error);
01203 if (dbus_error_is_set (&error)) {
01204 fprintf (stderr, "%s %d : Error sending msg: %s\n",
01205 __FILE__, __LINE__, error.message);
01206 dbus_message_unref (message);
01207 return FALSE;
01208 }
01209 if (reply == NULL) {
01210 dbus_message_unref (message);
01211 return FALSE;
01212 }
01213
01214 dbus_message_iter_init (reply, &iter);
01215
01216
01217 if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_NIL) {
01218
01219 fprintf (stderr,
01220 "%s %d : property '%s' for device '%s' does not "
01221 "exist\n", __FILE__, __LINE__, key, udi);
01222 dbus_message_unref (message);
01223 dbus_message_unref (reply);
01224 return FALSE;
01225 } else if (dbus_message_iter_get_arg_type (&iter) !=
01226 DBUS_TYPE_BOOLEAN) {
01227 fprintf (stderr,
01228 "%s %d : property '%s' for device '%s' is not "
01229 "of type bool\n", __FILE__, __LINE__, key, udi);
01230 dbus_message_unref (message);
01231 dbus_message_unref (reply);
01232 return FALSE;
01233 }
01234 value = dbus_message_iter_get_boolean (&iter);
01235
01236 dbus_message_unref (message);
01237 dbus_message_unref (reply);
01238 return value;
01239 }
01240
01241
01242
01243 static int
01244 hal_device_set_property_helper (LibHalContext *ctx,
01245 const char *udi,
01246 const char *key,
01247 int type,
01248 const char *str_value,
01249 dbus_int32_t int_value,
01250 dbus_uint64_t uint64_value,
01251 double double_value,
01252 dbus_bool_t bool_value)
01253 {
01254 DBusError error;
01255 DBusMessage *message;
01256 DBusMessage *reply;
01257 DBusMessageIter iter;
01258 char *method_name = NULL;
01259
01262 switch (type) {
01263 case DBUS_TYPE_NIL:
01264 method_name = "RemoveProperty";
01265 break;
01266 case DBUS_TYPE_STRING:
01267 method_name = "SetPropertyString";
01268 break;
01269 case DBUS_TYPE_INT32:
01270 case DBUS_TYPE_UINT64:
01271 method_name = "SetPropertyInteger";
01272 break;
01273 case DBUS_TYPE_DOUBLE:
01274 method_name = "SetPropertyDouble";
01275 break;
01276 case DBUS_TYPE_BOOLEAN:
01277 method_name = "SetPropertyBoolean";
01278 break;
01279
01280 default:
01281
01282 break;
01283 }
01284
01285 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
01286 "org.freedesktop.Hal.Device",
01287 method_name);
01288 if (message == NULL) {
01289 fprintf (stderr,
01290 "%s %d : Couldn't allocate D-BUS message\n",
01291 __FILE__, __LINE__);
01292 return FALSE;
01293 }
01294
01295 dbus_message_iter_init (message, &iter);
01296 dbus_message_iter_append_string (&iter, key);
01297 switch (type) {
01298 case DBUS_TYPE_NIL:
01299 dbus_message_iter_append_nil (&iter);
01300 break;
01301 case DBUS_TYPE_STRING:
01302 dbus_message_iter_append_string (&iter, str_value);
01303 break;
01304 case DBUS_TYPE_INT32:
01305 dbus_message_iter_append_int32 (&iter, int_value);
01306 break;
01307 case DBUS_TYPE_UINT64:
01308 dbus_message_iter_append_uint64 (&iter, uint64_value);
01309 break;
01310 case DBUS_TYPE_DOUBLE:
01311 dbus_message_iter_append_double (&iter, double_value);
01312 break;
01313 case DBUS_TYPE_BOOLEAN:
01314 dbus_message_iter_append_boolean (&iter, bool_value);
01315 break;
01316 }
01317
01318 dbus_error_init (&error);
01319 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01320 message, -1,
01321 &error);
01322 if (dbus_error_is_set (&error)) {
01323 fprintf (stderr, "%s %d: %s raised\n\"%s\"\n\n", __FILE__,
01324 __LINE__, error.name, error.message);
01325 dbus_message_unref (message);
01326 return FALSE;
01327 }
01328
01329 if (reply == NULL) {
01330 dbus_message_unref (message);
01331 return FALSE;
01332 }
01333
01334 return TRUE;
01335 }
01336
01347 dbus_bool_t
01348 hal_device_set_property_string (LibHalContext *ctx,
01349 const char *udi,
01350 const char *key, const char *value)
01351 {
01352 return hal_device_set_property_helper (ctx, udi, key,
01353 DBUS_TYPE_STRING,
01354 value, 0, 0, 0.0f, FALSE);
01355 }
01356
01367 dbus_bool_t
01368 hal_device_set_property_int (LibHalContext *ctx, const char *udi,
01369 const char *key, dbus_int32_t value)
01370 {
01371 return hal_device_set_property_helper (ctx, udi, key,
01372 DBUS_TYPE_INT32,
01373 NULL, value, 0, 0.0f, FALSE);
01374 }
01375
01386 dbus_bool_t
01387 hal_device_set_property_uint64 (LibHalContext *ctx, const char *udi,
01388 const char *key, dbus_uint64_t value)
01389 {
01390 return hal_device_set_property_helper (ctx, udi, key,
01391 DBUS_TYPE_UINT64,
01392 NULL, 0, value, 0.0f, FALSE);
01393 }
01394
01405 dbus_bool_t
01406 hal_device_set_property_double (LibHalContext *ctx, const char *udi,
01407 const char *key, double value)
01408 {
01409 return hal_device_set_property_helper (ctx, udi, key,
01410 DBUS_TYPE_DOUBLE,
01411 NULL, 0, 0, value, FALSE);
01412 }
01413
01424 dbus_bool_t
01425 hal_device_set_property_bool (LibHalContext *ctx, const char *udi,
01426 const char *key, dbus_bool_t value)
01427 {
01428 return hal_device_set_property_helper (ctx, udi, key,
01429 DBUS_TYPE_BOOLEAN,
01430 NULL, 0, 0, 0.0f, value);
01431 }
01432
01433
01442 dbus_bool_t
01443 hal_device_remove_property (LibHalContext *ctx,
01444 const char *udi, const char *key)
01445 {
01446 return hal_device_set_property_helper (ctx, udi, key, DBUS_TYPE_NIL,
01447
01448 NULL, 0, 0, 0.0f, FALSE);
01449 }
01450
01464 dbus_bool_t
01465 hal_device_lock (LibHalContext *ctx,
01466 const char *udi,
01467 const char *reason_to_lock,
01468 char **reason_why_locked)
01469 {
01470 DBusMessage *message;
01471 DBusMessageIter iter;
01472 DBusError error;
01473 DBusMessage *reply;
01474
01475 if (reason_why_locked != NULL)
01476 *reason_why_locked = NULL;
01477
01478 message = dbus_message_new_method_call ("org.freedesktop.Hal",
01479 udi,
01480 "org.freedesktop.Hal.Device",
01481 "Lock");
01482
01483 if (message == NULL) {
01484 fprintf (stderr,
01485 "%s %d : Couldn't allocate D-BUS message\n",
01486 __FILE__, __LINE__);
01487 return FALSE;
01488 }
01489
01490 dbus_message_iter_init (message, &iter);
01491 dbus_message_iter_append_string (&iter, reason_to_lock);
01492
01493 dbus_error_init (&error);
01494 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01495 message, -1,
01496 &error);
01497
01498 if (dbus_error_is_set (&error)) {
01499 if (strcmp (error.name,
01500 "org.freedesktop.Hal.DeviceAlreadyLocked") == 0) {
01501 if (reason_why_locked != NULL) {
01502 *reason_why_locked =
01503 dbus_malloc0 (strlen (error.message) + 1);
01504 strcpy (*reason_why_locked, error.message);
01505 }
01506 } else {
01507 fprintf (stderr, "%s %d: %s raised\n\"%s\"\n\n",
01508 __FILE__, __LINE__, error.name,
01509 error.message);
01510 }
01511
01512 dbus_message_unref (message);
01513 return FALSE;
01514 }
01515
01516 dbus_message_unref (message);
01517
01518 if (reply == NULL)
01519 return FALSE;
01520
01521 dbus_message_unref (reply);
01522
01523 return TRUE;
01524 }
01525
01534 dbus_bool_t
01535 hal_device_unlock (LibHalContext *ctx,
01536 const char *udi)
01537 {
01538 DBusMessage *message;
01539 DBusError error;
01540 DBusMessage *reply;
01541
01542 message = dbus_message_new_method_call ("org.freedesktop.Hal",
01543 udi,
01544 "org.freedesktop.Hal.Device",
01545 "Unlock");
01546
01547 if (message == NULL) {
01548 fprintf (stderr,
01549 "%s %d : Couldn't allocate D-BUS message\n",
01550 __FILE__, __LINE__);
01551 return FALSE;
01552 }
01553
01554 dbus_error_init (&error);
01555 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01556 message, -1,
01557 &error);
01558
01559 if (dbus_error_is_set (&error)) {
01560 fprintf (stderr, "%s %d: %s raised\n\"%s\"\n\n", __FILE__,
01561 __LINE__, error.name, error.message);
01562 dbus_message_unref (message);
01563 return FALSE;
01564 }
01565
01566 dbus_message_unref (message);
01567
01568 if (reply == NULL)
01569 return FALSE;
01570
01571 dbus_message_unref (reply);
01572
01573 return TRUE;
01574 }
01575
01576
01588 char *
01589 hal_agent_new_device (LibHalContext *ctx)
01590 {
01591 DBusError error;
01592 DBusMessage *message;
01593 DBusMessage *reply;
01594 DBusMessageIter iter;
01595 char *value;
01596 char *dbus_str;
01597
01598 message = dbus_message_new_method_call ("org.freedesktop.Hal",
01599 "/org/freedesktop/Hal/Manager",
01600 "org.freedesktop.Hal.AgentManager",
01601 "NewDevice");
01602 if (message == NULL) {
01603 fprintf (stderr,
01604 "%s %d : Couldn't allocate D-BUS message\n",
01605 __FILE__, __LINE__);
01606 return NULL;
01607 }
01608
01609 dbus_error_init (&error);
01610 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01611 message, -1,
01612 &error);
01613 if (dbus_error_is_set (&error)) {
01614 fprintf (stderr, "%s %d : Error sending msg: %s\n",
01615 __FILE__, __LINE__, error.message);
01616 dbus_message_unref (message);
01617 return NULL;
01618 }
01619 if (reply == NULL) {
01620 dbus_message_unref (message);
01621 return NULL;
01622 }
01623
01624 dbus_message_iter_init (reply, &iter);
01625
01626
01627 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING) {
01628 fprintf (stderr,
01629 "%s %d : expected a string in reply to NewDevice\n",
01630 __FILE__, __LINE__);
01631 dbus_message_unref (message);
01632 dbus_message_unref (reply);
01633 return NULL;
01634 }
01635
01636 dbus_str = dbus_message_iter_get_string (&iter);
01637 value = (char *) ((dbus_str != NULL) ? strdup (dbus_str) : NULL);
01638 if (value == NULL) {
01639 fprintf (stderr, "%s %d : error allocating memory\n",
01640 __FILE__, __LINE__);
01642 return NULL;
01643 }
01644 dbus_free (dbus_str);
01645
01646 dbus_message_unref (message);
01647 dbus_message_unref (reply);
01648 return value;
01649 }
01650
01651
01670 dbus_bool_t
01671 hal_agent_commit_to_gdl (LibHalContext *ctx,
01672 const char *temp_udi, const char *udi)
01673 {
01674 DBusError error;
01675 DBusMessage *message;
01676 DBusMessage *reply;
01677 DBusMessageIter iter;
01678
01679 message = dbus_message_new_method_call ("org.freedesktop.Hal",
01680 "/org/freedesktop/Hal/Manager",
01681 "org.freedesktop.Hal.AgentManager",
01682 "CommitToGdl");
01683 if (message == NULL) {
01684 fprintf (stderr,
01685 "%s %d : Couldn't allocate D-BUS message\n",
01686 __FILE__, __LINE__);
01687 return FALSE;
01688 }
01689
01690 dbus_message_iter_init (message, &iter);
01691 dbus_message_iter_append_string (&iter, temp_udi);
01692 dbus_message_iter_append_string (&iter, udi);
01693
01694 dbus_error_init (&error);
01695 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01696 message, -1,
01697 &error);
01698 if (dbus_error_is_set (&error)) {
01699 if (dbus_error_has_name
01700 (&error, "org.freedesktop.Hal.UdiInUse"))
01701 return FALSE;
01702 fprintf (stderr, "%s %d : Error sending msg: %s\n",
01703 __FILE__, __LINE__, error.message);
01704 dbus_message_unref (message);
01705 return FALSE;
01706 }
01707 if (reply == NULL) {
01708 dbus_message_unref (message);
01709 return FALSE;
01710 }
01711
01712 dbus_message_unref (message);
01713 dbus_message_unref (reply);
01714 return TRUE;
01715 }
01716
01728 dbus_bool_t
01729 hal_agent_remove_device (LibHalContext *ctx, const char *udi)
01730 {
01731 DBusError error;
01732 DBusMessage *message;
01733 DBusMessage *reply;
01734 DBusMessageIter iter;
01735
01736 message = dbus_message_new_method_call ("org.freedesktop.Hal",
01737 "/org/freedesktop/Hal/Manager",
01738 "org.freedesktop.Hal.AgentManager",
01739 "Remove");
01740 if (message == NULL) {
01741 fprintf (stderr,
01742 "%s %d : Couldn't allocate D-BUS message\n",
01743 __FILE__, __LINE__);
01744 return FALSE;
01745 }
01746
01747 dbus_message_iter_init (message, &iter);
01748 dbus_message_iter_append_string (&iter, udi);
01749
01750 dbus_error_init (&error);
01751 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01752 message, -1,
01753 &error);
01754 if (dbus_error_is_set (&error)) {
01755 fprintf (stderr, "%s %d : Error sending msg: %s\n",
01756 __FILE__, __LINE__, error.message);
01757 dbus_message_unref (message);
01758 return FALSE;
01759 }
01760 if (reply == NULL) {
01761 dbus_message_unref (message);
01762 return FALSE;
01763 }
01764
01765 dbus_message_unref (message);
01766 dbus_message_unref (reply);
01767 return TRUE;
01768 }
01769
01776 dbus_bool_t
01777 hal_device_exists (LibHalContext *ctx, const char *udi)
01778 {
01779 DBusError error;
01780 DBusMessage *message;
01781 DBusMessage *reply;
01782 DBusMessageIter iter;
01783 dbus_bool_t value;
01784
01785 message = dbus_message_new_method_call ("org.freedesktop.Hal",
01786 "/org/freedesktop/Hal/Manager",
01787 "org.freedesktop.Hal.Manager",
01788 "DeviceExists");
01789 if (message == NULL) {
01790 fprintf (stderr,
01791 "%s %d : Couldn't allocate D-BUS message\n",
01792 __FILE__, __LINE__);
01793 return FALSE;
01794 }
01795
01796 dbus_message_iter_init (message, &iter);
01797 dbus_message_iter_append_string (&iter, udi);
01798
01799 dbus_error_init (&error);
01800 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01801 message, -1,
01802 &error);
01803 if (dbus_error_is_set (&error)) {
01804 fprintf (stderr, "%s %d : Error sending msg: %s\n",
01805 __FILE__, __LINE__, error.message);
01806 dbus_message_unref (message);
01807 return FALSE;
01808 }
01809 if (reply == NULL) {
01810 dbus_message_unref (message);
01811 return FALSE;
01812 }
01813
01814 dbus_message_iter_init (reply, &iter);
01815
01816
01817 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_BOOLEAN) {
01818 fprintf (stderr,
01819 "%s %d : expected a bool in reply to DeviceExists\n",
01820 __FILE__, __LINE__);
01821 dbus_message_unref (message);
01822 dbus_message_unref (reply);
01823 return FALSE;
01824 }
01825
01826 value = dbus_message_iter_get_boolean (&iter);
01827
01828 dbus_message_unref (message);
01829 dbus_message_unref (reply);
01830 return value;
01831 }
01832
01840 dbus_bool_t
01841 hal_device_property_exists (LibHalContext *ctx,
01842 const char *udi, const char *key)
01843 {
01844 DBusError error;
01845 DBusMessage *message;
01846 DBusMessage *reply;
01847 DBusMessageIter iter;
01848 dbus_bool_t value;
01849
01850 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
01851 "org.freedesktop.Hal.Device",
01852 "PropertyExists");
01853 if (message == NULL) {
01854 fprintf (stderr,
01855 "%s %d : Couldn't allocate D-BUS message\n",
01856 __FILE__, __LINE__);
01857 return FALSE;
01858 }
01859
01860 dbus_message_iter_init (message, &iter);
01861 dbus_message_iter_append_string (&iter, key);
01862
01863 dbus_error_init (&error);
01864 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01865 message, -1,
01866 &error);
01867 if (dbus_error_is_set (&error)) {
01868 fprintf (stderr, "%s %d : Error sending msg: %s\n",
01869 __FILE__, __LINE__, error.message);
01870 dbus_message_unref (message);
01871 return FALSE;
01872 }
01873 if (reply == NULL) {
01874 dbus_message_unref (message);
01875 return FALSE;
01876 }
01877
01878 dbus_message_iter_init (reply, &iter);
01879
01880
01881 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_BOOLEAN) {
01882 fprintf (stderr, "%s %d : expected a bool in reply to "
01883 "PropertyExists\n", __FILE__, __LINE__);
01884 dbus_message_unref (message);
01885 dbus_message_unref (reply);
01886 return FALSE;
01887 }
01888
01889 value = dbus_message_iter_get_boolean (&iter);
01890
01891 dbus_message_unref (message);
01892 dbus_message_unref (reply);
01893 return value;
01894 }
01895
01903 dbus_bool_t
01904 hal_agent_merge_properties (LibHalContext *ctx,
01905 const char *target_udi, const char *source_udi)
01906 {
01907 DBusError error;
01908 DBusMessage *message;
01909 DBusMessage *reply;
01910 DBusMessageIter iter;
01911
01912 message = dbus_message_new_method_call ("org.freedesktop.Hal",
01913 "/org/freedesktop/Hal/Manager",
01914 "org.freedesktop.Hal.AgentManager",
01915 "MergeProperties");
01916 if (message == NULL) {
01917 fprintf (stderr,
01918 "%s %d : Couldn't allocate D-BUS message\n",
01919 __FILE__, __LINE__);
01920 return FALSE;
01921 }
01922
01923 dbus_message_iter_init (message, &iter);
01924 dbus_message_iter_append_string (&iter, target_udi);
01925 dbus_message_iter_append_string (&iter, source_udi);
01926
01927 dbus_error_init (&error);
01928 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01929 message, -1,
01930 &error);
01931 if (dbus_error_is_set (&error)) {
01932 if (dbus_error_has_name
01933 (&error, "org.freedesktop.Hal.NoSuchDevice"))
01934 return FALSE;
01935 fprintf (stderr, "%s %d : Error sending msg: %s\n",
01936 __FILE__, __LINE__, error.message);
01937 dbus_message_unref (message);
01938 return FALSE;
01939 }
01940 if (reply == NULL) {
01941 dbus_message_unref (message);
01942 return FALSE;
01943 }
01944
01945 dbus_message_unref (message);
01946 dbus_message_unref (reply);
01947 return TRUE;
01948 }
01949
01969 dbus_bool_t
01970 hal_agent_device_matches (LibHalContext *ctx,
01971 const char *udi1, const char *udi2,
01972 const char *property_namespace)
01973 {
01974 DBusError error;
01975 DBusMessage *message;
01976 DBusMessage *reply;
01977 DBusMessageIter iter;
01978 dbus_bool_t value;
01979
01980 message = dbus_message_new_method_call ("org.freedesktop.Hal",
01981 "/org/freedesktop/Hal/Manager",
01982 "org.freedesktop.Hal.AgentManager",
01983 "DeviceMatches");
01984 if (message == NULL) {
01985 fprintf (stderr,
01986 "%s %d : Couldn't allocate D-BUS message\n",
01987 __FILE__, __LINE__);
01988 return FALSE;
01989 }
01990
01991 dbus_message_iter_init (message, &iter);
01992 dbus_message_iter_append_string (&iter, udi1);
01993 dbus_message_iter_append_string (&iter, udi2);
01994 dbus_message_iter_append_string (&iter, property_namespace);
01995
01996 dbus_error_init (&error);
01997 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01998 message, -1,
01999 &error);
02000 if (dbus_error_is_set (&error)) {
02001 fprintf (stderr, "%s %d : Error sending msg: %s\n",
02002 __FILE__, __LINE__, error.message);
02003 dbus_message_unref (message);
02004 return FALSE;
02005 }
02006 if (reply == NULL) {
02007 dbus_message_unref (message);
02008 return FALSE;
02009 }
02010
02011 dbus_message_iter_init (reply, &iter);
02012 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_BOOLEAN) {
02013 fprintf (stderr,
02014 "%s %d : expected a bool in reply to DeviceMatches\n",
02015 __FILE__, __LINE__);
02016 dbus_message_unref (message);
02017 dbus_message_unref (reply);
02018 return FALSE;
02019 }
02020
02021 value = dbus_message_iter_get_boolean (&iter);
02022
02023 dbus_message_unref (message);
02024 dbus_message_unref (reply);
02025 return value;
02026 }
02027
02033 void
02034 hal_device_print (LibHalContext *ctx, const char *udi)
02035 {
02036 int type;
02037 char *key;
02038 LibHalPropertySet *pset;
02039 LibHalPropertySetIterator i;
02040
02041 printf ("device_id = %s\n", udi);
02042
02043 pset = hal_device_get_all_properties (ctx, udi);
02044
02045 for (hal_psi_init (&i, pset); hal_psi_has_more (&i);
02046 hal_psi_next (&i)) {
02047 type = hal_psi_get_type (&i);
02048 key = hal_psi_get_key (&i);
02049 switch (type) {
02050 case DBUS_TYPE_STRING:
02051 printf (" %s = %s (string)\n", key,
02052 hal_psi_get_string (&i));
02053 break;
02054 case DBUS_TYPE_INT32:
02055 printf (" %s = %d = 0x%x (int)\n", key,
02056 hal_psi_get_int (&i),
02057 hal_psi_get_int (&i));
02058 break;
02059 case DBUS_TYPE_UINT64:
02060 printf (" %s = %lld = 0x%llx (uint64)\n", key,
02061 hal_psi_get_uint64 (&i),
02062 hal_psi_get_uint64 (&i));
02063 break;
02064 case DBUS_TYPE_BOOLEAN:
02065 printf (" %s = %s (bool)\n", key,
02066 (hal_psi_get_bool (&i) ? "true" :
02067 "false"));
02068 break;
02069 case DBUS_TYPE_DOUBLE:
02070 printf (" %s = %g (double)\n", key,
02071 hal_psi_get_double (&i));
02072 break;
02073 default:
02074 printf (" *** unknown type for key %s\n", key);
02075 break;
02076 }
02077 }
02078 hal_free_property_set (pset);
02079 }
02080
02091 char **
02092 hal_manager_find_device_string_match (LibHalContext *ctx,
02093 const char *key,
02094 const char *value, int *num_devices)
02095 {
02096 int i;
02097 DBusError error;
02098 DBusMessage *message;
02099 DBusMessage *reply;
02100 DBusMessageIter iter;
02101 char **device_names;
02102 char **hal_device_names;
02103
02104 message = dbus_message_new_method_call ("org.freedesktop.Hal",
02105 "/org/freedesktop/Hal/Manager",
02106 "org.freedesktop.Hal.Manager",
02107 "FindDeviceStringMatch");
02108 if (message == NULL) {
02109 fprintf (stderr,
02110 "%s %d : Couldn't allocate D-BUS message\n",
02111 __FILE__, __LINE__);
02112 return NULL;
02113 }
02114
02115 dbus_message_iter_init (message, &iter);
02116 dbus_message_iter_append_string (&iter, key);
02117 dbus_message_iter_append_string (&iter, value);
02118
02119 dbus_error_init (&error);
02120 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
02121 message, -1,
02122 &error);
02123 if (dbus_error_is_set (&error)) {
02124 fprintf (stderr, "%s %d : Error sending msg: %s\n",
02125 __FILE__, __LINE__, error.message);
02126 dbus_message_unref (message);
02127 return NULL;
02128 }
02129 if (reply == NULL) {
02130 dbus_message_unref (message);
02131 return NULL;
02132 }
02133
02134 dbus_message_iter_init (reply, &iter);
02135 if (!dbus_message_iter_get_string_array (&iter,
02136 &device_names,
02137 num_devices)) {
02138 fprintf (stderr, "%s %d : wrong reply from hald\n",
02139 __FILE__, __LINE__);
02140 return NULL;
02141 }
02142
02143 dbus_message_unref (message);
02144 dbus_message_unref (reply);
02145
02146
02147
02148
02149
02150 hal_device_names = malloc (sizeof (char *) * ((*num_devices) + 1));
02151 if (hal_device_names == NULL)
02152 return NULL;
02155 for (i = 0; i < (*num_devices); i++) {
02156 hal_device_names[i] = strdup (device_names[i]);
02157 if (hal_device_names[i] == NULL)
02158 return NULL;
02160 }
02161 hal_device_names[i] = NULL;
02162
02163 dbus_free_string_array (device_names);
02164
02165 return hal_device_names;
02166 }
02167
02168
02177 dbus_bool_t
02178 hal_device_add_capability (LibHalContext *ctx,
02179 const char *udi, const char *capability)
02180 {
02181 DBusError error;
02182 DBusMessage *message;
02183 DBusMessage *reply;
02184 DBusMessageIter iter;
02185
02186 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
02187 "org.freedesktop.Hal.Device",
02188 "AddCapability");
02189 if (message == NULL) {
02190 fprintf (stderr,
02191 "%s %d : Couldn't allocate D-BUS message\n",
02192 __FILE__, __LINE__);
02193 return FALSE;
02194 }
02195
02196 dbus_message_iter_init (message, &iter);
02197 dbus_message_iter_append_string (&iter, capability);
02198
02199 dbus_error_init (&error);
02200 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
02201 message, -1,
02202 &error);
02203 if (dbus_error_is_set (&error)) {
02204 fprintf (stderr, "%s %d: %s raised\n\"%s\"\n\n", __FILE__,
02205 __LINE__, error.name, error.message);
02206 dbus_message_unref (message);
02207 return FALSE;
02208 }
02209
02210 if (reply == NULL) {
02211 dbus_message_unref (message);
02212 return FALSE;
02213 }
02214
02215 dbus_message_unref (reply);
02216 dbus_message_unref (message);
02217 return TRUE;
02218 }
02219
02229 dbus_bool_t
02230 hal_device_query_capability (LibHalContext *ctx,
02231 const char *udi, const char *capability)
02232 {
02233 char *caps;
02234
02235 caps = hal_device_get_property_string (ctx, udi, "info.capabilities");
02236
02237 if (caps != NULL)
02238 if (strstr (caps, capability) != NULL)
02239 return TRUE;
02240
02241 return FALSE;
02242 }
02243
02252 char **
02253 hal_find_device_by_capability (LibHalContext *ctx,
02254 const char *capability, int *num_devices)
02255 {
02256 int i;
02257 DBusError error;
02258 DBusMessage *message;
02259 DBusMessage *reply;
02260 DBusMessageIter iter;
02261 char **device_names;
02262 char **hal_device_names;
02263
02264 message = dbus_message_new_method_call ("org.freedesktop.Hal",
02265 "/org/freedesktop/Hal/Manager",
02266 "org.freedesktop.Hal.Manager",
02267 "FindDeviceByCapability");
02268 if (message == NULL) {
02269 fprintf (stderr,
02270 "%s %d : Couldn't allocate D-BUS message\n",
02271 __FILE__, __LINE__);
02272 return NULL;
02273 }
02274
02275 dbus_message_iter_init (message, &iter);
02276 dbus_message_iter_append_string (&iter, capability);
02277
02278 dbus_error_init (&error);
02279 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
02280 message, -1,
02281 &error);
02282 if (dbus_error_is_set (&error)) {
02283 fprintf (stderr, "%s %d : Error sending msg: %s\n",
02284 __FILE__, __LINE__, error.message);
02285 dbus_message_unref (message);
02286 return NULL;
02287 }
02288 if (reply == NULL) {
02289 dbus_message_unref (message);
02290 return NULL;
02291 }
02292
02293 dbus_message_iter_init (reply, &iter);
02294 if (!dbus_message_iter_get_string_array (&iter,
02295 &device_names,
02296 num_devices)) {
02297 fprintf (stderr, "%s %d : wrong reply from hald\n",
02298 __FILE__, __LINE__);
02299 return NULL;
02300 }
02301
02302 dbus_message_unref (message);
02303 dbus_message_unref (reply);
02304
02305
02306
02307
02308
02309 hal_device_names = malloc (sizeof (char *) * ((*num_devices) + 1));
02310 if (hal_device_names == NULL)
02311 return NULL;
02314 for (i = 0; i < (*num_devices); i++) {
02315 hal_device_names[i] = strdup (device_names[i]);
02316 if (hal_device_names[i] == NULL)
02317 return NULL;
02319 }
02320 hal_device_names[i] = NULL;
02321
02322 dbus_free_string_array (device_names);
02323
02324 return hal_device_names;
02325 }
02326
02334 int
02335 hal_device_property_watch_all (LibHalContext *ctx)
02336 {
02337 DBusError error;
02338
02339 dbus_error_init (&error);
02340
02341 dbus_bus_add_match (ctx->connection,
02342 "type='signal',"
02343 "interface='org.freedesktop.Hal.Device',"
02344 "sender='org.freedesktop.Hal'", &error);
02345 if (dbus_error_is_set (&error)) {
02346 fprintf (stderr, "%s %d : Error subscribing to signals, "
02347 "error=%s\r\n",
02348 __FILE__, __LINE__, error.message);
02349 return 1;
02350 }
02351 return 0;
02352 }
02353
02354
02366 int
02367 hal_device_add_property_watch (LibHalContext *ctx, const char *udi)
02368 {
02369 char buf[512];
02370 DBusError error;
02371
02372 dbus_error_init (&error);
02373
02374 snprintf (buf, 512,
02375 "type='signal',"
02376 "interface='org.freedesktop.Hal.Device',"
02377 "sender='org.freedesktop.Hal'," "path=%s", udi);
02378
02379 dbus_bus_add_match (ctx->connection, buf, &error);
02380 if (dbus_error_is_set (&error)) {
02381 fprintf (stderr, "%s %d : Error subscribing to signals, "
02382 "error=%s\r\n",
02383 __FILE__, __LINE__, error.message);
02384 return 1;
02385 }
02386 return 0;
02387 }
02388
02389
02397 int
02398 hal_device_remove_property_watch (LibHalContext *ctx, const char *udi)
02399 {
02400 char buf[512];
02401 DBusError error;
02402
02403 dbus_error_init (&error);
02404
02405 snprintf (buf, 512,
02406 "type='signal',"
02407 "interface='org.freedesktop.Hal.Device',"
02408 "sender='org.freedesktop.Hal'," "path=%s", udi);
02409
02410 dbus_bus_remove_match (ctx->connection, buf, &error);
02411 if (dbus_error_is_set (&error)) {
02412 fprintf (stderr, "%s %d : Error unsubscribing to signals, "
02413 "error=%s\r\n",
02414 __FILE__, __LINE__, error.message);
02415 return 1;
02416 }
02417 return 0;
02418 }
02419
02420