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
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
00166
00167
00169
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
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 ,
00503 NULL ,
00504 NULL ,
00505 NULL ,
00506 NULL ,
00507 NULL ,
00508 NULL
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
00547 if (ctx->functions == NULL)
00548 ctx->functions = &hal_null_functions;
00549
00550
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
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
00669
00670
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
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
00877 if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_NIL) {
00878
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
00948 if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_NIL) {
00949
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
01018 if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_NIL) {
01019
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
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
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
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
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
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
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
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
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
01780
01781
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
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
01936
01937
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