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
00027 #ifdef HAVE_CONFIG_H
00028 # include <config.h>
00029 #endif
00030
00031 #include <stdio.h>
00032 #include <stdlib.h>
00033 #include <string.h>
00034 #include <dbus/dbus.h>
00035
00036 #include "libhal.h"
00037
00038 #ifdef ENABLE_NLS
00039 # include <libintl.h>
00040 # define _(String) dgettext (GETTEXT_PACKAGE, String)
00041 # ifdef gettext_noop
00042 # define N_(String) gettext_noop (String)
00043 # else
00044 # define N_(String) (String)
00045 # endif
00046 #else
00047
00048 # define textdomain(String) (String)
00049 # define gettext(String) (String)
00050 # define dgettext(Domain,Message) (Message)
00051 # define dcgettext(Domain,Message,Type) (Message)
00052 # define bindtextdomain(Domain,Directory) (Domain)
00053 # define _(String)
00054 # define N_(String) (String)
00055 #endif
00056
00057 static char **libhal_get_string_array_from_iter (DBusMessageIter *iter, int *num_elements);
00058
00059 static dbus_bool_t libhal_property_fill_value_from_variant (LibHalProperty *p, DBusMessageIter *var_iter);
00060
00061
00062
00075 void
00076 libhal_free_string_array (char **str_array)
00077 {
00078 if (str_array != NULL) {
00079 int i;
00080
00081 for (i = 0; str_array[i] != NULL; i++) {
00082 free (str_array[i]);
00083 str_array[i] = NULL;
00084 }
00085 free (str_array);
00086 str_array = NULL;
00087 }
00088 }
00089
00090
00097 static char **
00098 libhal_get_string_array_from_iter (DBusMessageIter *iter, int *num_elements)
00099 {
00100 int count;
00101 char **buffer;
00102
00103 count = 0;
00104 buffer = (char **)malloc (sizeof (char *) * 8);
00105
00106 if (buffer == NULL)
00107 goto oom;
00108
00109 buffer[0] = NULL;
00110 while (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_STRING) {
00111 const char *value;
00112 char *str;
00113
00114 if ((count % 8) == 0 && count != 0) {
00115 buffer = realloc (buffer, sizeof (char *) * (count + 8));
00116 if (buffer == NULL)
00117 goto oom;
00118 }
00119
00120 dbus_message_iter_get_basic (iter, &value);
00121 str = strdup (value);
00122 if (str == NULL)
00123 goto oom;
00124
00125 buffer[count] = str;
00126
00127 dbus_message_iter_next(iter);
00128 count++;
00129 }
00130
00131 if ((count % 8) == 0) {
00132 buffer = realloc (buffer, sizeof (char *) * (count + 1));
00133 if (buffer == NULL)
00134 goto oom;
00135 }
00136
00137 buffer[count] = NULL;
00138 if (num_elements != NULL)
00139 *num_elements = count;
00140 return buffer;
00141
00142 oom:
00143 fprintf (stderr, "%s %d : error allocating memory\n", __FILE__, __LINE__);
00144 return NULL;
00145
00146 }
00147
00152 void
00153 libhal_free_string (char *str)
00154 {
00156 if (str != NULL) {
00157 free (str);
00158 str = NULL;
00159 }
00160 }
00161
00162
00164 struct LibHalPropertySet_s {
00165 unsigned int num_properties;
00166 LibHalProperty *properties_head;
00169 };
00170
00172 struct LibHalProperty_s {
00173 int type;
00174 char *key;
00177 union {
00178 char *str_value;
00179 dbus_int32_t int_value;
00181 dbus_uint64_t uint64_value;
00183 double double_value;
00184 dbus_bool_t bool_value;
00187 char **strlist_value;
00188 };
00189
00190 LibHalProperty *next;
00192 };
00193
00195 struct LibHalContext_s {
00196 DBusConnection *connection;
00197 dbus_bool_t is_initialized;
00198 dbus_bool_t is_shutdown;
00199 dbus_bool_t cache_enabled;
00200 dbus_bool_t is_direct;
00203 LibHalDeviceAdded device_added;
00204
00206 LibHalDeviceRemoved device_removed;
00207
00209 LibHalDeviceNewCapability device_new_capability;
00210
00212 LibHalDeviceLostCapability device_lost_capability;
00213
00215 LibHalDevicePropertyModified device_property_modified;
00216
00218 LibHalDeviceCondition device_condition;
00219
00220 void *user_data;
00221 };
00222
00230 dbus_bool_t
00231 libhal_ctx_set_user_data(LibHalContext *ctx, void *user_data)
00232 {
00233 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
00234 ctx->user_data = user_data;
00235 return TRUE;
00236 }
00237
00244 void*
00245 libhal_ctx_get_user_data(LibHalContext *ctx)
00246 {
00247 LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL);
00248 return ctx->user_data;
00249 }
00250
00251
00257 static dbus_bool_t
00258 libhal_property_fill_value_from_variant (LibHalProperty *p, DBusMessageIter *var_iter)
00259 {
00260 DBusMessageIter iter_array;
00261 switch (p->type) {
00262 case DBUS_TYPE_ARRAY:
00263 if (dbus_message_iter_get_element_type (var_iter) != DBUS_TYPE_STRING)
00264 return FALSE;
00265
00266 dbus_message_iter_recurse (var_iter, &iter_array);
00267 p->strlist_value = libhal_get_string_array_from_iter (&iter_array, NULL);
00268
00269 p->type = LIBHAL_PROPERTY_TYPE_STRLIST;
00270
00271 break;
00272 case DBUS_TYPE_STRING:
00273 {
00274 const char *v;
00275
00276 dbus_message_iter_get_basic (var_iter, &v);
00277
00278 p->str_value = strdup (v);
00279 if (p->str_value == NULL)
00280 return FALSE;
00281 p->type = LIBHAL_PROPERTY_TYPE_STRING;
00282
00283 break;
00284 }
00285 case DBUS_TYPE_INT32:
00286 {
00287 dbus_int32_t v;
00288
00289 dbus_message_iter_get_basic (var_iter, &v);
00290
00291 p->int_value = v;
00292 p->type = LIBHAL_PROPERTY_TYPE_INT32;
00293
00294 break;
00295 }
00296 case DBUS_TYPE_UINT64:
00297 {
00298 dbus_uint64_t v;
00299
00300 dbus_message_iter_get_basic (var_iter, &v);
00301
00302 p->uint64_value = v;
00303 p->type = LIBHAL_PROPERTY_TYPE_UINT64;
00304
00305 break;
00306 }
00307 case DBUS_TYPE_DOUBLE:
00308 {
00309 double v;
00310
00311 dbus_message_iter_get_basic (var_iter, &v);
00312
00313 p->double_value = v;
00314 p->type = LIBHAL_PROPERTY_TYPE_DOUBLE;
00315
00316 break;
00317 }
00318 case DBUS_TYPE_BOOLEAN:
00319 {
00320 double v;
00321
00322 dbus_message_iter_get_basic (var_iter, &v);
00323
00324 p->double_value = v;
00325 p->type = LIBHAL_PROPERTY_TYPE_BOOLEAN;
00326
00327 break;
00328 }
00329 default:
00331 break;
00332 }
00333
00334 return TRUE;
00335 }
00336
00346 LibHalPropertySet *
00347 libhal_device_get_all_properties (LibHalContext *ctx, const char *udi, DBusError *error)
00348 {
00349 DBusMessage *message;
00350 DBusMessage *reply;
00351 DBusMessageIter reply_iter;
00352 DBusMessageIter dict_iter;
00353 LibHalPropertySet *result;
00354 LibHalProperty *p_last;
00355 DBusError _error;
00356
00357 LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL);
00358
00359 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
00360 "org.freedesktop.Hal.Device",
00361 "GetAllProperties");
00362
00363 if (message == NULL) {
00364 fprintf (stderr,
00365 "%s %d : Couldn't allocate D-BUS message\n",
00366 __FILE__, __LINE__);
00367 return NULL;
00368 }
00369
00370 dbus_error_init (&_error);
00371 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
00372 message, -1,
00373 &_error);
00374
00375 dbus_move_error (&_error, error);
00376 if (error != NULL && dbus_error_is_set (error)) {
00377 fprintf (stderr,
00378 "%s %d : %s\n",
00379 __FILE__, __LINE__, error->message);
00380
00381 dbus_message_unref (message);
00382 return NULL;
00383 }
00384
00385 if (reply == NULL) {
00386 dbus_message_unref (message);
00387 return NULL;
00388 }
00389
00390 dbus_message_iter_init (reply, &reply_iter);
00391
00392 result = malloc (sizeof (LibHalPropertySet));
00393 if (result == NULL)
00394 goto oom;
00395
00396
00397
00398
00400
00401
00402
00403
00404 result->properties_head = NULL;
00405 result->num_properties = 0;
00406
00407 if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_ARRAY &&
00408 dbus_message_iter_get_element_type (&reply_iter) != DBUS_TYPE_DICT_ENTRY) {
00409 fprintf (stderr, "%s %d : error, expecting an array of dict entries\n",
00410 __FILE__, __LINE__);
00411 dbus_message_unref (message);
00412 dbus_message_unref (reply);
00413 return NULL;
00414 }
00415
00416 dbus_message_iter_recurse (&reply_iter, &dict_iter);
00417
00418 p_last = NULL;
00419
00420 while (dbus_message_iter_get_arg_type (&dict_iter) == DBUS_TYPE_DICT_ENTRY)
00421 {
00422 DBusMessageIter dict_entry_iter, var_iter;
00423 const char *key;
00424 LibHalProperty *p;
00425
00426 dbus_message_iter_recurse (&dict_iter, &dict_entry_iter);
00427
00428 dbus_message_iter_get_basic (&dict_entry_iter, &key);
00429
00430 p = malloc (sizeof (LibHalProperty));
00431 if (p == NULL)
00432 goto oom;
00433
00434 p->next = NULL;
00435
00436 if (result->num_properties == 0)
00437 result->properties_head = p;
00438
00439 if (p_last != NULL)
00440 p_last->next = p;
00441
00442 p_last = p;
00443
00444 p->key = strdup (key);
00445 if (p->key == NULL)
00446 goto oom;
00447
00448 dbus_message_iter_next (&dict_entry_iter);
00449
00450 dbus_message_iter_recurse (&dict_entry_iter, &var_iter);
00451
00452
00453 p->type = dbus_message_iter_get_arg_type (&var_iter);
00454
00455 result->num_properties++;
00456
00457 if(!libhal_property_fill_value_from_variant (p, &var_iter))
00458 goto oom;
00459
00460 dbus_message_iter_next (&dict_iter);
00461 }
00462
00463 dbus_message_unref (message);
00464 dbus_message_unref (reply);
00465
00466 return result;
00467
00468 oom:
00469 fprintf (stderr,
00470 "%s %d : error allocating memory\n",
00471 __FILE__, __LINE__);
00473 return NULL;
00474 }
00475
00480 void
00481 libhal_free_property_set (LibHalPropertySet * set)
00482 {
00483 LibHalProperty *p;
00484 LibHalProperty *q;
00485
00486 if (set == NULL)
00487 return;
00488
00489 for (p = set->properties_head; p != NULL; p = q) {
00490 free (p->key);
00491 if (p->type == DBUS_TYPE_STRING)
00492 free (p->str_value);
00493 if (p->type == LIBHAL_PROPERTY_TYPE_STRLIST)
00494 libhal_free_string_array (p->strlist_value);
00495 q = p->next;
00496 free (p);
00497 }
00498 free (set);
00499 }
00500
00506 unsigned int
00507 libhal_property_set_get_num_elems (LibHalPropertySet *set)
00508 {
00509 unsigned int num_elems;
00510 LibHalProperty *p;
00511
00512 if (set == NULL)
00513 return 0;
00514
00515 num_elems = 0;
00516 for (p = set->properties_head; p != NULL; p = p->next)
00517 num_elems++;
00518
00519 return num_elems;
00520 }
00521
00522
00528 void
00529 libhal_psi_init (LibHalPropertySetIterator * iter, LibHalPropertySet * set)
00530 {
00531 if (set == NULL)
00532 return;
00533
00534 iter->set = set;
00535 iter->index = 0;
00536 iter->cur_prop = set->properties_head;
00537 }
00538
00539
00546 dbus_bool_t
00547 libhal_psi_has_more (LibHalPropertySetIterator * iter)
00548 {
00549 return iter->index < iter->set->num_properties;
00550 }
00551
00556 void
00557 libhal_psi_next (LibHalPropertySetIterator * iter)
00558 {
00559 iter->index++;
00560 iter->cur_prop = iter->cur_prop->next;
00561 }
00562
00568 LibHalPropertyType
00569 libhal_psi_get_type (LibHalPropertySetIterator * iter)
00570 {
00571 return iter->cur_prop->type;
00572 }
00573
00582 char *
00583 libhal_psi_get_key (LibHalPropertySetIterator * iter)
00584 {
00585 return iter->cur_prop->key;
00586 }
00587
00596 char *
00597 libhal_psi_get_string (LibHalPropertySetIterator * iter)
00598 {
00599 return iter->cur_prop->str_value;
00600 }
00601
00607 dbus_int32_t
00608 libhal_psi_get_int (LibHalPropertySetIterator * iter)
00609 {
00610 return iter->cur_prop->int_value;
00611 }
00612
00618 dbus_uint64_t
00619 libhal_psi_get_uint64 (LibHalPropertySetIterator * iter)
00620 {
00621 return iter->cur_prop->uint64_value;
00622 }
00623
00629 double
00630 libhal_psi_get_double (LibHalPropertySetIterator * iter)
00631 {
00632 return iter->cur_prop->double_value;
00633 }
00634
00640 dbus_bool_t
00641 libhal_psi_get_bool (LibHalPropertySetIterator * iter)
00642 {
00643 return iter->cur_prop->bool_value;
00644 }
00645
00651 char **
00652 libhal_psi_get_strlist (LibHalPropertySetIterator * iter)
00653 {
00654 return iter->cur_prop->strlist_value;
00655 }
00656
00657
00658 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00659 static DBusHandlerResult
00660 filter_func (DBusConnection * connection,
00661 DBusMessage * message, void *user_data)
00662 {
00663 const char *object_path;
00664 DBusError error;
00665 LibHalContext *ctx = (LibHalContext *) user_data;
00666
00667 if (ctx->is_shutdown)
00668 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
00669
00670 dbus_error_init (&error);
00671
00672 object_path = dbus_message_get_path (message);
00673
00674
00675
00676 if (dbus_message_is_signal (message, "org.freedesktop.Hal.Manager",
00677 "DeviceAdded")) {
00678 char *udi;
00679 if (dbus_message_get_args (message, &error,
00680 DBUS_TYPE_STRING, &udi,
00681 DBUS_TYPE_INVALID)) {
00682 if (ctx->device_added != NULL) {
00683 ctx->device_added (ctx, udi);
00684 }
00685 }
00686 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
00687 } else if (dbus_message_is_signal (message, "org.freedesktop.Hal.Manager", "DeviceRemoved")) {
00688 char *udi;
00689 if (dbus_message_get_args (message, &error,
00690 DBUS_TYPE_STRING, &udi,
00691 DBUS_TYPE_INVALID)) {
00692 if (ctx->device_removed != NULL) {
00693 ctx->device_removed (ctx, udi);
00694 }
00695 }
00696 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
00697 } else if (dbus_message_is_signal (message, "org.freedesktop.Hal.Manager","NewCapability")) {
00698 char *udi;
00699 char *capability;
00700 if (dbus_message_get_args (message, &error,
00701 DBUS_TYPE_STRING, &udi,
00702 DBUS_TYPE_STRING, &capability,
00703 DBUS_TYPE_INVALID)) {
00704 if (ctx->device_new_capability != NULL) {
00705 ctx->device_new_capability (ctx, udi, capability);
00706 }
00707 }
00708 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
00709 } else if (dbus_message_is_signal (message, "org.freedesktop.Hal.Device", "Condition")) {
00710 char *condition_name;
00711 char *condition_detail;
00712 if (dbus_message_get_args (message, &error,
00713 DBUS_TYPE_STRING, &condition_name,
00714 DBUS_TYPE_STRING, &condition_detail,
00715 DBUS_TYPE_INVALID)) {
00716 if (ctx->device_condition != NULL) {
00717 ctx->device_condition (ctx, object_path, condition_name, condition_detail);
00718 }
00719 }
00720 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
00721 } else if (dbus_message_is_signal (message, "org.freedesktop.Hal.Device", "PropertyModified")) {
00722 if (ctx->device_property_modified != NULL) {
00723 int i;
00724 char *key;
00725 dbus_bool_t removed;
00726 dbus_bool_t added;
00727 int num_modifications;
00728 DBusMessageIter iter;
00729 DBusMessageIter iter_array;
00730
00731 dbus_message_iter_init (message, &iter);
00732 dbus_message_iter_get_basic (&iter, &num_modifications);
00733 dbus_message_iter_next (&iter);
00734
00735 dbus_message_iter_recurse (&iter, &iter_array);
00736
00737 for (i = 0; i < num_modifications; i++) {
00738 DBusMessageIter iter_struct;
00739
00740 dbus_message_iter_recurse (&iter_array, &iter_struct);
00741
00742 dbus_message_iter_get_basic (&iter_struct, &key);
00743 dbus_message_iter_next (&iter_struct);
00744 dbus_message_iter_get_basic (&iter_struct, &removed);
00745 dbus_message_iter_next (&iter_struct);
00746 dbus_message_iter_get_basic (&iter_struct, &added);
00747
00748 ctx->device_property_modified (ctx,
00749 object_path,
00750 key, removed,
00751 added);
00752
00753 dbus_message_iter_next (&iter_array);
00754 }
00755
00756 }
00757 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
00758 }
00759
00760 LIBHAL_FREE_DBUS_ERROR(&error);
00761 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
00762 }
00763
00764 #endif
00765
00766
00767 static dbus_bool_t libhal_already_initialized_once = FALSE;
00768
00769 #if 0
00770
00788 LibHalContext*
00789 libhal_initialize (const LibHalFunctions * cb_functions,
00790 dbus_bool_t use_cache)
00791 {
00792 DBusError error;
00793 LibHalContext *ctx;
00794
00795 if (!libhal_already_initialized_once) {
00796 bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
00797 bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
00798
00799 libhal_already_initialized_once = TRUE;
00800 }
00801
00802 ctx = malloc (sizeof (LibHalContext));
00803 if (ctx == NULL) {
00804 fprintf (stderr, "%s %d : Cannot allocated %d bytes!\n",
00805 __FILE__, __LINE__, sizeof (LibHalContext));
00806 return NULL;
00807 }
00808
00809 ctx->is_initialized = FALSE;
00810 ctx->is_shutdown = FALSE;
00811
00812 ctx->cache_enabled = use_cache;
00813
00814 ctx->functions = cb_functions;
00815
00816 if (ctx->functions == NULL)
00817 ctx->functions = &libhal_null_functions;
00818
00819
00820
00821 ctx->connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
00822 if (ctx->connection == NULL) {
00823 fprintf (stderr,
00824 "%s %d : Error connecting to system bus: %s\n",
00825 __FILE__, __LINE__, error.message);
00826 dbus_error_free (&error);
00827 return NULL;
00828 }
00829
00830 if (ctx->main_loop_integration != NULL) {
00831
00832 ctx->main_loop_integration (ctx, ctx->connection);
00833 }
00834
00835 if (!dbus_connection_add_filter
00836 (ctx->connection, filter_func, ctx, NULL)) {
00837 fprintf (stderr,
00838 "%s %d : Error creating connection handler\r\n",
00839 __FILE__, __LINE__);
00841 return NULL;
00842 }
00843
00844 dbus_bus_add_match (ctx->connection,
00845 "type='signal',"
00846 "interface='org.freedesktop.Hal.Manager',"
00847 "sender='org.freedesktop.Hal',"
00848 "path='/org/freedesktop/Hal/Manager'", &error);
00849 if (dbus_error_is_set (&error)) {
00850 fprintf (stderr, "%s %d : Error subscribing to signals, "
00851 "error=%s\r\n",
00852 __FILE__, __LINE__, error.message);
00854 return NULL;
00855 }
00856
00857 ctx->is_initialized = TRUE;
00858 return ctx;
00859 }
00860
00867 int
00868 libhal_shutdown (LibHalContext *ctx)
00869 {
00870 DBusError error;
00871
00872 if (!ctx->is_initialized)
00873 return 1;
00874
00875
00876
00877
00878 dbus_bus_remove_match (ctx->connection,
00879 "type='signal',"
00880 "interface='org.freedesktop.Hal.Manager',"
00881 "sender='org.freedesktop.Hal',"
00882 "path='/org/freedesktop/Hal/Manager'", &error);
00883 if (dbus_error_is_set (&error)) {
00884 fprintf (stderr, "%s %d : Error removing match rule, error=%s\r\n",
00885 __FILE__, __LINE__, error.message);
00886 }
00887
00888
00889
00890
00891 ctx->is_shutdown = TRUE;
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906 return 0;
00907 }
00908 #endif
00909
00921 char **
00922 libhal_get_all_devices (LibHalContext *ctx, int *num_devices, DBusError *error)
00923 {
00924 DBusMessage *message;
00925 DBusMessage *reply;
00926 DBusMessageIter iter_array, reply_iter;
00927 char **hal_device_names;
00928 DBusError _error;
00929
00930 LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL);
00931
00932 *num_devices = 0;
00933
00934 message = dbus_message_new_method_call ("org.freedesktop.Hal",
00935 "/org/freedesktop/Hal/Manager",
00936 "org.freedesktop.Hal.Manager",
00937 "GetAllDevices");
00938 if (message == NULL) {
00939 fprintf (stderr, "%s %d : Could not allocate D-BUS message\n", __FILE__, __LINE__);
00940 return NULL;
00941 }
00942
00943 dbus_error_init (&_error);
00944 reply = dbus_connection_send_with_reply_and_block (ctx->connection, message, -1, &_error);
00945
00946 dbus_move_error (&_error, error);
00947 if (error != NULL && dbus_error_is_set (error)) {
00948 dbus_message_unref (message);
00949 return NULL;
00950 }
00951 if (reply == NULL) {
00952 dbus_message_unref (message);
00953 return NULL;
00954 }
00955
00956
00957 dbus_message_iter_init (reply, &reply_iter);
00958
00959 if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_ARRAY) {
00960 fprintf (stderr, "%s %d : wrong reply from hald. Expecting an array.\n", __FILE__, __LINE__);
00961 return NULL;
00962 }
00963
00964 dbus_message_iter_recurse (&reply_iter, &iter_array);
00965
00966 hal_device_names = libhal_get_string_array_from_iter (&iter_array, num_devices);
00967
00968 dbus_message_unref (reply);
00969 dbus_message_unref (message);
00970
00971 return hal_device_names;
00972 }
00973
00987 LibHalPropertyType
00988 libhal_device_get_property_type (LibHalContext *ctx, const char *udi, const char *key, DBusError *error)
00989 {
00990 DBusMessage *message;
00991 DBusMessage *reply;
00992 DBusMessageIter iter, reply_iter;
00993 int type;
00994 DBusError _error;
00995
00996 LIBHAL_CHECK_LIBHALCONTEXT(ctx, LIBHAL_PROPERTY_TYPE_INVALID);
00997
00998 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
00999 "org.freedesktop.Hal.Device",
01000 "GetPropertyType");
01001 if (message == NULL) {
01002 fprintf (stderr, "%s %d : Couldn't allocate D-BUS message\n", __FILE__, __LINE__);
01003 return LIBHAL_PROPERTY_TYPE_INVALID;
01004 }
01005
01006 dbus_message_iter_init_append (message, &iter);
01007 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
01008
01009 dbus_error_init (&_error);
01010 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01011 message, -1,
01012 &_error);
01013
01014 dbus_move_error (&_error, error);
01015 if (error != NULL && dbus_error_is_set (error)) {
01016 dbus_message_unref (message);
01017 return LIBHAL_PROPERTY_TYPE_INVALID;
01018 }
01019 if (reply == NULL) {
01020 dbus_message_unref (message);
01021 return LIBHAL_PROPERTY_TYPE_INVALID;
01022 }
01023
01024 dbus_message_iter_init (reply, &reply_iter);
01025 dbus_message_iter_get_basic (&reply_iter, &type);
01026
01027 dbus_message_unref (message);
01028 dbus_message_unref (reply);
01029
01030 return type;
01031 }
01032
01048 char **
01049 libhal_device_get_property_strlist (LibHalContext *ctx, const char *udi, const char *key, DBusError *error)
01050 {
01051 DBusMessage *message;
01052 DBusMessage *reply;
01053 DBusMessageIter iter, iter_array, reply_iter;
01054 char **our_strings;
01055 DBusError _error;
01056
01057 LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL);
01058
01059 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
01060 "org.freedesktop.Hal.Device",
01061 "GetPropertyStringList");
01062 if (message == NULL) {
01063 fprintf (stderr,
01064 "%s %d : Couldn't allocate D-BUS message\n",
01065 __FILE__, __LINE__);
01066 return NULL;
01067 }
01068
01069 dbus_message_iter_init_append (message, &iter);
01070 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
01071
01072 dbus_error_init (&_error);
01073 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01074 message, -1,
01075 &_error);
01076
01077 dbus_move_error (&_error, error);
01078 if (error != NULL && dbus_error_is_set (error)) {
01079 dbus_message_unref (message);
01080 return NULL;
01081 }
01082 if (reply == NULL) {
01083 dbus_message_unref (message);
01084 return NULL;
01085 }
01086
01087 dbus_message_iter_init (reply, &reply_iter);
01088
01089 if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_ARRAY) {
01090 fprintf (stderr, "%s %d : wrong reply from hald. Expecting an array.\n", __FILE__, __LINE__);
01091 return NULL;
01092 }
01093
01094 dbus_message_iter_recurse (&reply_iter, &iter_array);
01095
01096 our_strings = libhal_get_string_array_from_iter (&iter_array, NULL);
01097
01098 dbus_message_unref (reply);
01099 dbus_message_unref (message);
01100
01101 return our_strings;
01102 }
01103
01117 char *
01118 libhal_device_get_property_string (LibHalContext *ctx,
01119 const char *udi, const char *key, DBusError *error)
01120 {
01121 DBusMessage *message;
01122 DBusMessage *reply;
01123 DBusMessageIter iter, reply_iter;
01124 char *value;
01125 char *dbus_str;
01126 DBusError _error;
01127
01128 LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL);
01129
01130 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
01131 "org.freedesktop.Hal.Device",
01132 "GetPropertyString");
01133
01134 if (message == NULL) {
01135 fprintf (stderr,
01136 "%s %d : Couldn't allocate D-BUS message\n",
01137 __FILE__, __LINE__);
01138 return NULL;
01139 }
01140
01141 dbus_message_iter_init_append (message, &iter);
01142 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
01143
01144 dbus_error_init (&_error);
01145 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01146 message, -1,
01147 &_error);
01148
01149 dbus_move_error (&_error, error);
01150 if (error != NULL && dbus_error_is_set (error)) {
01151 dbus_message_unref (message);
01152 return NULL;
01153 }
01154 if (reply == NULL) {
01155 dbus_message_unref (message);
01156 return NULL;
01157 }
01158
01159 dbus_message_iter_init (reply, &reply_iter);
01160
01161
01162 if (dbus_message_iter_get_arg_type (&reply_iter) !=
01163 DBUS_TYPE_STRING) {
01164 dbus_message_unref (message);
01165 dbus_message_unref (reply);
01166 return NULL;
01167 }
01168
01169 dbus_message_iter_get_basic (&reply_iter, &dbus_str);
01170 value = (char *) ((dbus_str != NULL) ? strdup (dbus_str) : NULL);
01171 if (value == NULL) {
01172 fprintf (stderr, "%s %d : error allocating memory\n",
01173 __FILE__, __LINE__);
01175 return NULL;
01176 }
01177
01178 dbus_message_unref (message);
01179 dbus_message_unref (reply);
01180 return value;
01181 }
01182
01192 dbus_int32_t
01193 libhal_device_get_property_int (LibHalContext *ctx,
01194 const char *udi, const char *key, DBusError *error)
01195 {
01196 DBusMessage *message;
01197 DBusMessage *reply;
01198 DBusMessageIter iter, reply_iter;
01199 dbus_int32_t value;
01200 DBusError _error;
01201
01202 LIBHAL_CHECK_LIBHALCONTEXT(ctx, -1);
01203
01204 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
01205 "org.freedesktop.Hal.Device",
01206 "GetPropertyInteger");
01207 if (message == NULL) {
01208 fprintf (stderr,
01209 "%s %d : Couldn't allocate D-BUS message\n",
01210 __FILE__, __LINE__);
01211 return -1;
01212 }
01213
01214 dbus_message_iter_init_append (message, &iter);
01215 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
01216
01217 dbus_error_init (&_error);
01218 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01219 message, -1,
01220 &_error);
01221
01222 dbus_move_error (&_error, error);
01223 if (error != NULL && dbus_error_is_set (error)) {
01224 dbus_message_unref (message);
01225 return -1;
01226 }
01227 if (reply == NULL) {
01228 dbus_message_unref (message);
01229 return -1;
01230 }
01231
01232 dbus_message_iter_init (reply, &reply_iter);
01233
01234
01235 if (dbus_message_iter_get_arg_type (&reply_iter) !=
01236 DBUS_TYPE_INT32) {
01237 fprintf (stderr,
01238 "%s %d : property '%s' for device '%s' is not "
01239 "of type integer\n", __FILE__, __LINE__, key,
01240 udi);
01241 dbus_message_unref (message);
01242 dbus_message_unref (reply);
01243 return -1;
01244 }
01245 dbus_message_iter_get_basic (&reply_iter, &value);
01246
01247 dbus_message_unref (message);
01248 dbus_message_unref (reply);
01249 return value;
01250 }
01251
01261 dbus_uint64_t
01262 libhal_device_get_property_uint64 (LibHalContext *ctx,
01263 const char *udi, const char *key, DBusError *error)
01264 {
01265 DBusMessage *message;
01266 DBusMessage *reply;
01267 DBusMessageIter iter, reply_iter;
01268 dbus_uint64_t value;
01269 DBusError _error;
01270
01271 LIBHAL_CHECK_LIBHALCONTEXT(ctx, -1);
01272
01273 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
01274 "org.freedesktop.Hal.Device",
01275 "GetPropertyInteger");
01276 if (message == NULL) {
01277 fprintf (stderr,
01278 "%s %d : Couldn't allocate D-BUS message\n",
01279 __FILE__, __LINE__);
01280 return -1;
01281 }
01282
01283 dbus_message_iter_init_append (message, &iter);
01284 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
01285
01286 dbus_error_init (&_error);
01287 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01288 message, -1,
01289 &_error);
01290
01291 dbus_move_error (&_error, error);
01292 if (error != NULL && dbus_error_is_set (error)) {
01293 dbus_message_unref (message);
01294 return -1;
01295 }
01296 if (reply == NULL) {
01297 dbus_message_unref (message);
01298 return -1;
01299 }
01300
01301 dbus_message_iter_init (reply, &reply_iter);
01302
01303 if (dbus_message_iter_get_arg_type (&reply_iter) !=
01304 DBUS_TYPE_UINT64) {
01305 fprintf (stderr,
01306 "%s %d : property '%s' for device '%s' is not "
01307 "of type integer\n", __FILE__, __LINE__, key,
01308 udi);
01309 dbus_message_unref (message);
01310 dbus_message_unref (reply);
01311 return -1;
01312 }
01313 dbus_message_iter_get_basic (&reply_iter, &value);
01314
01315 dbus_message_unref (message);
01316 dbus_message_unref (reply);
01317 return value;
01318 }
01319
01329 double
01330 libhal_device_get_property_double (LibHalContext *ctx,
01331 const char *udi, const char *key, DBusError *error)
01332 {
01333 DBusMessage *message;
01334 DBusMessage *reply;
01335 DBusMessageIter iter, reply_iter;
01336 double value;
01337 DBusError _error;
01338
01339 LIBHAL_CHECK_LIBHALCONTEXT(ctx, -1.0);
01340
01341 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
01342 "org.freedesktop.Hal.Device",
01343 "GetPropertyDouble");
01344 if (message == NULL) {
01345 fprintf (stderr,
01346 "%s %d : Couldn't allocate D-BUS message\n",
01347 __FILE__, __LINE__);
01348 return -1.0f;
01349 }
01350
01351 dbus_message_iter_init_append (message, &iter);
01352 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
01353
01354 dbus_error_init (&_error);
01355 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01356 message, -1,
01357 &_error);
01358
01359 dbus_move_error (&_error, error);
01360 if (error != NULL && dbus_error_is_set (error)) {
01361 dbus_message_unref (message);
01362 return -1.0f;
01363 }
01364 if (reply == NULL) {
01365 dbus_message_unref (message);
01366 return -1.0f;
01367 }
01368
01369 dbus_message_iter_init (reply, &reply_iter);
01370
01371
01372 if (dbus_message_iter_get_arg_type (&reply_iter) !=
01373 DBUS_TYPE_DOUBLE) {
01374 fprintf (stderr,
01375 "%s %d : property '%s' for device '%s' is not "
01376 "of type double\n", __FILE__, __LINE__, key, udi);
01377 dbus_message_unref (message);
01378 dbus_message_unref (reply);
01379 return -1.0f;
01380 }
01381 dbus_message_iter_get_basic (&reply_iter, &value);
01382
01383 dbus_message_unref (message);
01384 dbus_message_unref (reply);
01385 return (double) value;
01386 }
01387
01397 dbus_bool_t
01398 libhal_device_get_property_bool (LibHalContext *ctx,
01399 const char *udi, const char *key, DBusError *error)
01400 {
01401 DBusMessage *message;
01402 DBusMessage *reply;
01403 DBusMessageIter iter, reply_iter;
01404 dbus_bool_t value;
01405 DBusError _error;
01406
01407 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
01408
01409 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
01410 "org.freedesktop.Hal.Device",
01411 "GetPropertyBoolean");
01412 if (message == NULL) {
01413 fprintf (stderr,
01414 "%s %d : Couldn't allocate D-BUS message\n",
01415 __FILE__, __LINE__);
01416 return FALSE;
01417 }
01418
01419 dbus_message_iter_init_append (message, &iter);
01420 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
01421
01422 dbus_error_init (&_error);
01423 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01424 message, -1,
01425 &_error);
01426
01427 dbus_move_error (&_error, error);
01428 if (error != NULL && dbus_error_is_set (error)) {
01429 dbus_message_unref (message);
01430 return FALSE;
01431 }
01432 if (reply == NULL) {
01433 dbus_message_unref (message);
01434 return FALSE;
01435 }
01436
01437 dbus_message_iter_init (reply, &reply_iter);
01438
01439
01440 if (dbus_message_iter_get_arg_type (&reply_iter) !=
01441 DBUS_TYPE_BOOLEAN) {
01442 fprintf (stderr,
01443 "%s %d : property '%s' for device '%s' is not "
01444 "of type bool\n", __FILE__, __LINE__, key, udi);
01445 dbus_message_unref (message);
01446 dbus_message_unref (reply);
01447 return FALSE;
01448 }
01449 dbus_message_iter_get_basic (&reply_iter, &value);
01450
01451 dbus_message_unref (message);
01452 dbus_message_unref (reply);
01453 return value;
01454 }
01455
01456
01457
01458 static dbus_bool_t
01459 libhal_device_set_property_helper (LibHalContext *ctx,
01460 const char *udi,
01461 const char *key,
01462 int type,
01463 const char *str_value,
01464 dbus_int32_t int_value,
01465 dbus_uint64_t uint64_value,
01466 double double_value,
01467 dbus_bool_t bool_value,
01468 DBusError *error)
01469 {
01470 DBusMessage *message;
01471 DBusMessage *reply;
01472 DBusMessageIter iter;
01473 char *method_name = NULL;
01474
01475 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
01476
01478 switch (type) {
01479 case DBUS_TYPE_INVALID:
01480 method_name = "RemoveProperty";
01481 break;
01482 case DBUS_TYPE_STRING:
01483 method_name = "SetPropertyString";
01484 break;
01485 case DBUS_TYPE_INT32:
01486 case DBUS_TYPE_UINT64:
01487 method_name = "SetPropertyInteger";
01488 break;
01489 case DBUS_TYPE_DOUBLE:
01490 method_name = "SetPropertyDouble";
01491 break;
01492 case DBUS_TYPE_BOOLEAN:
01493 method_name = "SetPropertyBoolean";
01494 break;
01495
01496 default:
01497
01498 break;
01499 }
01500
01501 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
01502 "org.freedesktop.Hal.Device",
01503 method_name);
01504 if (message == NULL) {
01505 fprintf (stderr,
01506 "%s %d : Couldn't allocate D-BUS message\n",
01507 __FILE__, __LINE__);
01508 return FALSE;
01509 }
01510
01511 dbus_message_iter_init_append (message, &iter);
01512 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
01513 switch (type) {
01514 case DBUS_TYPE_STRING:
01515 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &str_value);
01516 break;
01517 case DBUS_TYPE_INT32:
01518 dbus_message_iter_append_basic (&iter, DBUS_TYPE_INT32, &int_value);
01519 break;
01520 case DBUS_TYPE_UINT64:
01521 dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT64, &uint64_value);
01522 break;
01523 case DBUS_TYPE_DOUBLE:
01524 dbus_message_iter_append_basic (&iter, DBUS_TYPE_DOUBLE, &double_value);
01525 break;
01526 case DBUS_TYPE_BOOLEAN:
01527 dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN, &bool_value);
01528 break;
01529 }
01530
01531
01532 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01533 message, -1,
01534 error);
01535 if (dbus_error_is_set (error)) {
01536 dbus_message_unref (message);
01537 return FALSE;
01538 }
01539
01540 if (reply == NULL) {
01541 dbus_message_unref (message);
01542 return FALSE;
01543 }
01544
01545 dbus_message_unref (message);
01546 dbus_message_unref (reply);
01547
01548 return TRUE;
01549 }
01550
01563 dbus_bool_t
01564 libhal_device_set_property_string (LibHalContext *ctx,
01565 const char *udi,
01566 const char *key,
01567 const char *value,
01568 DBusError *error)
01569 {
01570 return libhal_device_set_property_helper (ctx, udi, key,
01571 DBUS_TYPE_STRING,
01572 value, 0, 0, 0.0f, FALSE, error);
01573 }
01574
01587 dbus_bool_t
01588 libhal_device_set_property_int (LibHalContext *ctx, const char *udi,
01589 const char *key, dbus_int32_t value, DBusError *error)
01590 {
01591 return libhal_device_set_property_helper (ctx, udi, key,
01592 DBUS_TYPE_INT32,
01593 NULL, value, 0, 0.0f, FALSE, error);
01594 }
01595
01608 dbus_bool_t
01609 libhal_device_set_property_uint64 (LibHalContext *ctx, const char *udi,
01610 const char *key, dbus_uint64_t value, DBusError *error)
01611 {
01612 return libhal_device_set_property_helper (ctx, udi, key,
01613 DBUS_TYPE_UINT64,
01614 NULL, 0, value, 0.0f, FALSE, error);
01615 }
01616
01629 dbus_bool_t
01630 libhal_device_set_property_double (LibHalContext *ctx, const char *udi,
01631 const char *key, double value, DBusError *error)
01632 {
01633 return libhal_device_set_property_helper (ctx, udi, key,
01634 DBUS_TYPE_DOUBLE,
01635 NULL, 0, 0, value, FALSE, error);
01636 }
01637
01650 dbus_bool_t
01651 libhal_device_set_property_bool (LibHalContext *ctx, const char *udi,
01652 const char *key, dbus_bool_t value, DBusError *error)
01653 {
01654 return libhal_device_set_property_helper (ctx, udi, key,
01655 DBUS_TYPE_BOOLEAN,
01656 NULL, 0, 0, 0.0f, value, error);
01657 }
01658
01659
01670 dbus_bool_t
01671 libhal_device_remove_property (LibHalContext *ctx,
01672 const char *udi, const char *key, DBusError *error)
01673 {
01674 return libhal_device_set_property_helper (ctx, udi, key, DBUS_TYPE_INVALID,
01675
01676 NULL, 0, 0, 0.0f, FALSE, error);
01677 }
01678
01691 dbus_bool_t
01692 libhal_device_property_strlist_append (LibHalContext *ctx,
01693 const char *udi,
01694 const char *key,
01695 const char *value,
01696 DBusError *error)
01697 {
01698 DBusMessage *message;
01699 DBusMessage *reply;
01700 DBusMessageIter iter;
01701
01702 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
01703
01704 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
01705 "org.freedesktop.Hal.Device",
01706 "StringListAppend");
01707 if (message == NULL) {
01708 fprintf (stderr,
01709 "%s %d : Couldn't allocate D-BUS message\n",
01710 __FILE__, __LINE__);
01711 return FALSE;
01712 }
01713 dbus_message_iter_init_append (message, &iter);
01714 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
01715 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &value);
01716
01717 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01718 message, -1,
01719 error);
01720 if (dbus_error_is_set (error)) {
01721 dbus_message_unref (message);
01722 return FALSE;
01723 }
01724 if (reply == NULL) {
01725 dbus_message_unref (message);
01726 return FALSE;
01727 }
01728 return TRUE;
01729 }
01730
01743 dbus_bool_t
01744 libhal_device_property_strlist_prepend (LibHalContext *ctx,
01745 const char *udi,
01746 const char *key,
01747 const char *value,
01748 DBusError *error)
01749 {
01750 DBusMessage *message;
01751 DBusMessage *reply;
01752 DBusMessageIter iter;
01753
01754 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
01755
01756 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
01757 "org.freedesktop.Hal.Device",
01758 "StringListPrepend");
01759 if (message == NULL) {
01760 fprintf (stderr,
01761 "%s %d : Couldn't allocate D-BUS message\n",
01762 __FILE__, __LINE__);
01763 return FALSE;
01764 }
01765 dbus_message_iter_init_append (message, &iter);
01766 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
01767 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &value);
01768
01769 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01770 message, -1,
01771 error);
01772 if (dbus_error_is_set (error)) {
01773 dbus_message_unref (message);
01774 return FALSE;
01775 }
01776 if (reply == NULL) {
01777 dbus_message_unref (message);
01778 return FALSE;
01779 }
01780 return TRUE;
01781 }
01782
01795 dbus_bool_t
01796 libhal_device_property_strlist_remove_index (LibHalContext *ctx,
01797 const char *udi,
01798 const char *key,
01799 unsigned int index,
01800 DBusError *error)
01801 {
01802 DBusMessage *message;
01803 DBusMessage *reply;
01804 DBusMessageIter iter;
01805
01806 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
01807
01808 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
01809 "org.freedesktop.Hal.Device",
01810 "StringListRemoveIndex");
01811 if (message == NULL) {
01812 fprintf (stderr,
01813 "%s %d : Couldn't allocate D-BUS message\n",
01814 __FILE__, __LINE__);
01815 return FALSE;
01816 }
01817 dbus_message_iter_init_append (message, &iter);
01818 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
01819 dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT32, &index);
01820
01821 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01822 message, -1,
01823 error);
01824 if (dbus_error_is_set (error)) {
01825 dbus_message_unref (message);
01826 return FALSE;
01827 }
01828 if (reply == NULL) {
01829 dbus_message_unref (message);
01830 return FALSE;
01831 }
01832 return TRUE;
01833 }
01834
01847 dbus_bool_t
01848 libhal_device_property_strlist_remove (LibHalContext *ctx,
01849 const char *udi,
01850 const char *key,
01851 const char *value, DBusError *error)
01852 {
01853 DBusMessage *message;
01854 DBusMessage *reply;
01855 DBusMessageIter iter;
01856
01857 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
01858
01859 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
01860 "org.freedesktop.Hal.Device",
01861 "StringListRemove");
01862 if (message == NULL) {
01863 fprintf (stderr,
01864 "%s %d : Couldn't allocate D-BUS message\n",
01865 __FILE__, __LINE__);
01866 return FALSE;
01867 }
01868 dbus_message_iter_init_append (message, &iter);
01869 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
01870 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &value);
01871
01872 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01873 message, -1,
01874 error);
01875 if (dbus_error_is_set (error)) {
01876 dbus_message_unref (message);
01877 return FALSE;
01878 }
01879 if (reply == NULL) {
01880 dbus_message_unref (message);
01881 return FALSE;
01882 }
01883 return TRUE;
01884 }
01885
01886
01901 dbus_bool_t
01902 libhal_device_lock (LibHalContext *ctx,
01903 const char *udi,
01904 const char *reason_to_lock,
01905 char **reason_why_locked, DBusError *error)
01906 {
01907 DBusMessage *message;
01908 DBusMessageIter iter;
01909 DBusMessage *reply;
01910
01911 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
01912
01913 if (reason_why_locked != NULL)
01914 *reason_why_locked = NULL;
01915
01916 message = dbus_message_new_method_call ("org.freedesktop.Hal",
01917 udi,
01918 "org.freedesktop.Hal.Device",
01919 "Lock");
01920
01921 if (message == NULL) {
01922 fprintf (stderr,
01923 "%s %d : Couldn't allocate D-BUS message\n",
01924 __FILE__, __LINE__);
01925 return FALSE;
01926 }
01927
01928 dbus_message_iter_init_append (message, &iter);
01929 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &reason_to_lock);
01930
01931
01932 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01933 message, -1,
01934 error);
01935
01936 if (dbus_error_is_set (error)) {
01937 if (strcmp (error->name,
01938 "org.freedesktop.Hal.DeviceAlreadyLocked") == 0) {
01939 if (reason_why_locked != NULL) {
01940 *reason_why_locked =
01941 dbus_malloc0 (strlen (error->message) + 1);
01942 strcpy (*reason_why_locked, error->message);
01943 }
01944 }
01945
01946 dbus_message_unref (message);
01947 return FALSE;
01948 }
01949
01950 dbus_message_unref (message);
01951
01952 if (reply == NULL)
01953 return FALSE;
01954
01955 dbus_message_unref (reply);
01956
01957 return TRUE;
01958 }
01959
01969 dbus_bool_t
01970 libhal_device_unlock (LibHalContext *ctx,
01971 const char *udi, DBusError *error)
01972 {
01973 DBusMessage *message;
01974 DBusMessage *reply;
01975
01976 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
01977
01978 message = dbus_message_new_method_call ("org.freedesktop.Hal",
01979 udi,
01980 "org.freedesktop.Hal.Device",
01981 "Unlock");
01982
01983 if (message == NULL) {
01984 fprintf (stderr,
01985 "%s %d : Couldn't allocate D-BUS message\n",
01986 __FILE__, __LINE__);
01987 return FALSE;
01988 }
01989
01990
01991 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
01992 message, -1,
01993 error);
01994
01995 if (dbus_error_is_set (error)) {
01996 dbus_message_unref (message);
01997 return FALSE;
01998 }
01999
02000 dbus_message_unref (message);
02001
02002 if (reply == NULL)
02003 return FALSE;
02004
02005 dbus_message_unref (reply);
02006
02007 return TRUE;
02008 }
02009
02010
02024 char *
02025 libhal_new_device (LibHalContext *ctx, DBusError *error)
02026 {
02027 DBusMessage *message;
02028 DBusMessage *reply;
02029 DBusMessageIter reply_iter;
02030 char *value;
02031 char *dbus_str;
02032
02033 LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL);
02034
02035 message = dbus_message_new_method_call ("org.freedesktop.Hal",
02036 "/org/freedesktop/Hal/Manager",
02037 "org.freedesktop.Hal.Manager",
02038 "NewDevice");
02039 if (message == NULL) {
02040 fprintf (stderr,
02041 "%s %d : Couldn't allocate D-BUS message\n",
02042 __FILE__, __LINE__);
02043 return NULL;
02044 }
02045
02046
02047 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
02048 message, -1,
02049 error);
02050 if (dbus_error_is_set (error)) {
02051 dbus_message_unref (message);
02052 return NULL;
02053 }
02054 if (reply == NULL) {
02055 dbus_message_unref (message);
02056 return NULL;
02057 }
02058
02059 dbus_message_iter_init (reply, &reply_iter);
02060
02061
02062 if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_STRING) {
02063 fprintf (stderr,
02064 "%s %d : expected a string in reply to NewDevice\n",
02065 __FILE__, __LINE__);
02066 dbus_message_unref (message);
02067 dbus_message_unref (reply);
02068 return NULL;
02069 }
02070
02071 dbus_message_iter_get_basic (&reply_iter, &dbus_str);
02072 value = (char *) ((dbus_str != NULL) ? strdup (dbus_str) : NULL);
02073 if (value == NULL) {
02074 fprintf (stderr, "%s %d : error allocating memory\n",
02075 __FILE__, __LINE__);
02076 }
02077
02078 dbus_message_unref (message);
02079 dbus_message_unref (reply);
02080 return value;
02081 }
02082
02083
02104 dbus_bool_t
02105 libhal_device_commit_to_gdl (LibHalContext *ctx,
02106 const char *temp_udi, const char *udi, DBusError *error)
02107 {
02108 DBusMessage *message;
02109 DBusMessage *reply;
02110 DBusMessageIter iter;
02111
02112 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
02113
02114 message = dbus_message_new_method_call ("org.freedesktop.Hal",
02115 "/org/freedesktop/Hal/Manager",
02116 "org.freedesktop.Hal.Manager",
02117 "CommitToGdl");
02118 if (message == NULL) {
02119 fprintf (stderr,
02120 "%s %d : Couldn't allocate D-BUS message\n",
02121 __FILE__, __LINE__);
02122 return FALSE;
02123 }
02124
02125 dbus_message_iter_init_append (message, &iter);
02126 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &temp_udi);
02127 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &udi);
02128
02129
02130 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
02131 message, -1,
02132 error);
02133 if (dbus_error_is_set (error)) {
02134 dbus_message_unref (message);
02135 return FALSE;
02136 }
02137 if (reply == NULL) {
02138 dbus_message_unref (message);
02139 return FALSE;
02140 }
02141
02142 dbus_message_unref (message);
02143 dbus_message_unref (reply);
02144 return TRUE;
02145 }
02146
02160 dbus_bool_t
02161 libhal_remove_device (LibHalContext *ctx, const char *udi, DBusError *error)
02162 {
02163 DBusMessage *message;
02164 DBusMessage *reply;
02165 DBusMessageIter iter;
02166
02167 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
02168
02169 message = dbus_message_new_method_call ("org.freedesktop.Hal",
02170 "/org/freedesktop/Hal/Manager",
02171 "org.freedesktop.Hal.Manager",
02172 "Remove");
02173 if (message == NULL) {
02174 fprintf (stderr,
02175 "%s %d : Couldn't allocate D-BUS message\n",
02176 __FILE__, __LINE__);
02177 return FALSE;
02178 }
02179
02180 dbus_message_iter_init_append (message, &iter);
02181 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &udi);
02182
02183
02184 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
02185 message, -1,
02186 error);
02187 if (dbus_error_is_set (error)) {
02188 dbus_message_unref (message);
02189 return FALSE;
02190 }
02191 if (reply == NULL) {
02192 dbus_message_unref (message);
02193 return FALSE;
02194 }
02195
02196 dbus_message_unref (message);
02197 dbus_message_unref (reply);
02198 return TRUE;
02199 }
02200
02209 dbus_bool_t
02210 libhal_device_exists (LibHalContext *ctx, const char *udi, DBusError *error)
02211 {
02212 DBusMessage *message;
02213 DBusMessage *reply;
02214 DBusMessageIter iter, reply_iter;
02215 dbus_bool_t value;
02216 DBusError _error;
02217
02218 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
02219
02220 message = dbus_message_new_method_call ("org.freedesktop.Hal",
02221 "/org/freedesktop/Hal/Manager",
02222 "org.freedesktop.Hal.Manager",
02223 "DeviceExists");
02224 if (message == NULL) {
02225 fprintf (stderr,
02226 "%s %d : Couldn't allocate D-BUS message\n",
02227 __FILE__, __LINE__);
02228 return FALSE;
02229 }
02230
02231 dbus_message_iter_init_append (message, &iter);
02232 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &udi);
02233
02234 dbus_error_init (&_error);
02235 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
02236 message, -1,
02237 &_error);
02238
02239 dbus_move_error (&_error, error);
02240 if (error != NULL && dbus_error_is_set (error)) {
02241 dbus_message_unref (message);
02242 return FALSE;
02243 }
02244 if (reply == NULL) {
02245 dbus_message_unref (message);
02246 return FALSE;
02247 }
02248
02249 dbus_message_iter_init (reply, &reply_iter);
02250
02251
02252 if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_BOOLEAN) {
02253 fprintf (stderr,
02254 "%s %d : expected a bool in reply to DeviceExists\n",
02255 __FILE__, __LINE__);
02256 dbus_message_unref (message);
02257 dbus_message_unref (reply);
02258 return FALSE;
02259 }
02260
02261 dbus_message_iter_get_basic (&reply_iter, &value);
02262
02263 dbus_message_unref (message);
02264 dbus_message_unref (reply);
02265 return value;
02266 }
02267
02277 dbus_bool_t
02278 libhal_device_property_exists (LibHalContext *ctx,
02279 const char *udi, const char *key, DBusError *error)
02280 {
02281 DBusMessage *message;
02282 DBusMessage *reply;
02283 DBusMessageIter iter, reply_iter;
02284 dbus_bool_t value;
02285 DBusError _error;
02286
02287 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
02288
02289 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
02290 "org.freedesktop.Hal.Device",
02291 "PropertyExists");
02292 if (message == NULL) {
02293 fprintf (stderr,
02294 "%s %d : Couldn't allocate D-BUS message\n",
02295 __FILE__, __LINE__);
02296 return FALSE;
02297 }
02298
02299 dbus_message_iter_init_append (message, &iter);
02300 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
02301
02302 dbus_error_init (&_error);
02303 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
02304 message, -1,
02305 &_error);
02306
02307 dbus_move_error (&_error, error);
02308 if (error != NULL && dbus_error_is_set (error)) {
02309 dbus_message_unref (message);
02310 return FALSE;
02311 }
02312 if (reply == NULL) {
02313 dbus_message_unref (message);
02314 return FALSE;
02315 }
02316
02317 dbus_message_iter_init (reply, &reply_iter);
02318
02319
02320 if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_BOOLEAN) {
02321 fprintf (stderr, "%s %d : expected a bool in reply to "
02322 "PropertyExists\n", __FILE__, __LINE__);
02323 dbus_message_unref (message);
02324 dbus_message_unref (reply);
02325 return FALSE;
02326 }
02327
02328 dbus_message_iter_get_basic (&reply_iter, &value);
02329
02330 dbus_message_unref (message);
02331 dbus_message_unref (reply);
02332 return value;
02333 }
02334
02344 dbus_bool_t
02345 libhal_merge_properties (LibHalContext *ctx,
02346 const char *target_udi, const char *source_udi, DBusError *error)
02347 {
02348 DBusMessage *message;
02349 DBusMessage *reply;
02350 DBusMessageIter iter;
02351
02352 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
02353
02354 message = dbus_message_new_method_call ("org.freedesktop.Hal",
02355 "/org/freedesktop/Hal/Manager",
02356 "org.freedesktop.Hal.Manager",
02357 "MergeProperties");
02358 if (message == NULL) {
02359 fprintf (stderr,
02360 "%s %d : Couldn't allocate D-BUS message\n",
02361 __FILE__, __LINE__);
02362 return FALSE;
02363 }
02364
02365 dbus_message_iter_init_append (message, &iter);
02366 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &target_udi);
02367 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &source_udi);
02368
02369
02370 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
02371 message, -1,
02372 error);
02373 if (dbus_error_is_set (error)) {
02374 dbus_message_unref (message);
02375 return FALSE;
02376 }
02377 if (reply == NULL) {
02378 dbus_message_unref (message);
02379 return FALSE;
02380 }
02381
02382 dbus_message_unref (message);
02383 dbus_message_unref (reply);
02384 return TRUE;
02385 }
02386
02408 dbus_bool_t
02409 libhal_device_matches (LibHalContext *ctx,
02410 const char *udi1, const char *udi2,
02411 const char *property_namespace, DBusError *error)
02412 {
02413 DBusMessage *message;
02414 DBusMessage *reply;
02415 DBusMessageIter iter, reply_iter;
02416 dbus_bool_t value;
02417 DBusError _error;
02418
02419 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
02420
02421 message = dbus_message_new_method_call ("org.freedesktop.Hal",
02422 "/org/freedesktop/Hal/Manager",
02423 "org.freedesktop.Hal.Manager",
02424 "DeviceMatches");
02425 if (message == NULL) {
02426 fprintf (stderr,
02427 "%s %d : Couldn't allocate D-BUS message\n",
02428 __FILE__, __LINE__);
02429 return FALSE;
02430 }
02431
02432 dbus_message_iter_init_append (message, &iter);
02433 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, udi1);
02434 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, udi2);
02435 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, property_namespace);
02436
02437 dbus_error_init (&_error);
02438 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
02439 message, -1,
02440 &_error);
02441
02442 dbus_move_error (&_error, error);
02443 if (error != NULL && dbus_error_is_set (error)) {
02444 dbus_message_unref (message);
02445 return FALSE;
02446 }
02447 if (reply == NULL) {
02448 dbus_message_unref (message);
02449 return FALSE;
02450 }
02451
02452 dbus_message_iter_init (reply, &reply_iter);
02453
02454 if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_BOOLEAN) {
02455 fprintf (stderr,
02456 "%s %d : expected a bool in reply to DeviceMatches\n",
02457 __FILE__, __LINE__);
02458 dbus_message_unref (message);
02459 dbus_message_unref (reply);
02460 return FALSE;
02461 }
02462
02463 dbus_message_iter_get_basic (&reply_iter, &value);
02464
02465 dbus_message_unref (message);
02466 dbus_message_unref (reply);
02467 return value;
02468 }
02469
02479 dbus_bool_t
02480 libhal_device_print (LibHalContext *ctx, const char *udi, DBusError *error)
02481 {
02482 int type;
02483 char *key;
02484 LibHalPropertySet *pset;
02485 LibHalPropertySetIterator i;
02486
02487 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
02488
02489 printf ("device_id = %s\n", udi);
02490
02491 if ((pset = libhal_device_get_all_properties (ctx, udi, error)) == NULL)
02492 return FALSE;
02493
02494 for (libhal_psi_init (&i, pset); libhal_psi_has_more (&i);
02495 libhal_psi_next (&i)) {
02496 type = libhal_psi_get_type (&i);
02497 key = libhal_psi_get_key (&i);
02498
02499 switch (type) {
02500 case LIBHAL_PROPERTY_TYPE_STRING:
02501 printf (" %s = '%s' (string)\n", key,
02502 libhal_psi_get_string (&i));
02503 break;
02504 case LIBHAL_PROPERTY_TYPE_INT32:
02505 printf (" %s = %d = 0x%x (int)\n", key,
02506 libhal_psi_get_int (&i),
02507 libhal_psi_get_int (&i));
02508 break;
02509 case LIBHAL_PROPERTY_TYPE_UINT64:
02510 printf (" %s = %lld = 0x%llx (uint64)\n", key,
02511 libhal_psi_get_uint64 (&i),
02512 libhal_psi_get_uint64 (&i));
02513 break;
02514 case LIBHAL_PROPERTY_TYPE_BOOLEAN:
02515 printf (" %s = %s (bool)\n", key,
02516 (libhal_psi_get_bool (&i) ? "true" :
02517 "false"));
02518 break;
02519 case LIBHAL_PROPERTY_TYPE_DOUBLE:
02520 printf (" %s = %g (double)\n", key,
02521 libhal_psi_get_double (&i));
02522 break;
02523 case LIBHAL_PROPERTY_TYPE_STRLIST:
02524 {
02525 unsigned int j;
02526 char **str_list;
02527
02528 str_list = libhal_psi_get_strlist (&i);
02529 printf (" %s = [", key);
02530 for (j = 0; str_list[j] != NULL; j++) {
02531 printf ("'%s'", str_list[j]);
02532 if (str_list[j+1] != NULL)
02533 printf (", ");
02534 }
02535 printf ("] (string list)\n");
02536
02537 break;
02538 }
02539 default:
02540 printf (" *** unknown type for key %s\n", key);
02541 break;
02542 }
02543 }
02544
02545 libhal_free_property_set (pset);
02546
02547 return TRUE;
02548 }
02549
02562 char **
02563 libhal_manager_find_device_string_match (LibHalContext *ctx,
02564 const char *key,
02565 const char *value, int *num_devices, DBusError *error)
02566 {
02567 DBusMessage *message;
02568 DBusMessage *reply;
02569 DBusMessageIter iter, iter_array, reply_iter;
02570 char **hal_device_names;
02571 DBusError _error;
02572
02573 LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL);
02574
02575 message = dbus_message_new_method_call ("org.freedesktop.Hal",
02576 "/org/freedesktop/Hal/Manager",
02577 "org.freedesktop.Hal.Manager",
02578 "FindDeviceStringMatch");
02579 if (message == NULL) {
02580 fprintf (stderr,
02581 "%s %d : Couldn't allocate D-BUS message\n",
02582 __FILE__, __LINE__);
02583 return NULL;
02584 }
02585
02586 dbus_message_iter_init_append (message, &iter);
02587 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
02588 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &value);
02589
02590 dbus_error_init (&_error);
02591 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
02592 message, -1,
02593 &_error);
02594
02595 dbus_move_error (&_error, error);
02596 if (error != NULL && dbus_error_is_set (error)) {
02597 dbus_message_unref (message);
02598 return NULL;
02599 }
02600 if (reply == NULL) {
02601 dbus_message_unref (message);
02602 return NULL;
02603 }
02604
02605 dbus_message_iter_init (reply, &reply_iter);
02606
02607 if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_ARRAY) {
02608 fprintf (stderr, "%s %d : wrong reply from hald. Expecting an array.\n", __FILE__, __LINE__);
02609 return NULL;
02610 }
02611
02612 dbus_message_iter_recurse (&reply_iter, &iter_array);
02613
02614 hal_device_names = libhal_get_string_array_from_iter (&iter_array, num_devices);
02615
02616 dbus_message_unref (reply);
02617 dbus_message_unref (message);
02618
02619 return hal_device_names;
02620 }
02621
02622
02633 dbus_bool_t
02634 libhal_device_add_capability (LibHalContext *ctx,
02635 const char *udi, const char *capability, DBusError *error)
02636 {
02637 DBusMessage *message;
02638 DBusMessage *reply;
02639 DBusMessageIter iter;
02640
02641 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
02642
02643 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
02644 "org.freedesktop.Hal.Device",
02645 "AddCapability");
02646 if (message == NULL) {
02647 fprintf (stderr,
02648 "%s %d : Couldn't allocate D-BUS message\n",
02649 __FILE__, __LINE__);
02650 return FALSE;
02651 }
02652
02653 dbus_message_iter_init_append (message, &iter);
02654 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &capability);
02655
02656
02657 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
02658 message, -1,
02659 error);
02660 if (dbus_error_is_set (error)) {
02661 dbus_message_unref (message);
02662 return FALSE;
02663 }
02664
02665 if (reply == NULL) {
02666 dbus_message_unref (message);
02667 return FALSE;
02668 }
02669
02670 dbus_message_unref (reply);
02671 dbus_message_unref (message);
02672 return TRUE;
02673 }
02674
02686 dbus_bool_t
02687 libhal_device_query_capability (LibHalContext *ctx, const char *udi, const char *capability, DBusError *error)
02688 {
02689 char **caps;
02690 unsigned int i;
02691 dbus_bool_t ret;
02692
02693 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
02694
02695 ret = FALSE;
02696
02697 caps = libhal_device_get_property_strlist (ctx, udi, "info.capabilities", error);
02698 if (caps != NULL) {
02699 for (i = 0; caps[i] != NULL; i++) {
02700 if (strcmp (caps[i], capability) == 0) {
02701 ret = TRUE;
02702 break;
02703 }
02704 }
02705 libhal_free_string_array (caps);
02706 }
02707
02708 return ret;
02709 }
02710
02721 char **
02722 libhal_find_device_by_capability (LibHalContext *ctx,
02723 const char *capability, int *num_devices, DBusError *error)
02724 {
02725 DBusMessage *message;
02726 DBusMessage *reply;
02727 DBusMessageIter iter, iter_array, reply_iter;
02728 char **hal_device_names;
02729 DBusError _error;
02730
02731 LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL);
02732
02733 message = dbus_message_new_method_call ("org.freedesktop.Hal",
02734 "/org/freedesktop/Hal/Manager",
02735 "org.freedesktop.Hal.Manager",
02736 "FindDeviceByCapability");
02737 if (message == NULL) {
02738 fprintf (stderr,
02739 "%s %d : Couldn't allocate D-BUS message\n",
02740 __FILE__, __LINE__);
02741 return NULL;
02742 }
02743
02744 dbus_message_iter_init_append (message, &iter);
02745 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &capability);
02746
02747 dbus_error_init (&_error);
02748 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
02749 message, -1,
02750 &_error);
02751
02752 dbus_move_error (&_error, error);
02753 if (error != NULL && dbus_error_is_set (error)) {
02754 dbus_message_unref (message);
02755 return NULL;
02756 }
02757 if (reply == NULL) {
02758 dbus_message_unref (message);
02759 return NULL;
02760 }
02761
02762 dbus_message_iter_init (reply, &reply_iter);
02763
02764 if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_ARRAY) {
02765 fprintf (stderr, "%s %d : wrong reply from hald. Expecting an array.\n", __FILE__, __LINE__);
02766 return NULL;
02767 }
02768
02769 dbus_message_iter_recurse (&reply_iter, &iter_array);
02770
02771 hal_device_names = libhal_get_string_array_from_iter (&iter_array, num_devices);
02772
02773 dbus_message_unref (reply);
02774 dbus_message_unref (message);
02775
02776 return hal_device_names;
02777 }
02778
02787 dbus_bool_t
02788 libhal_device_property_watch_all (LibHalContext *ctx, DBusError *error)
02789 {
02790 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
02791
02792 dbus_bus_add_match (ctx->connection,
02793 "type='signal',"
02794 "interface='org.freedesktop.Hal.Device',"
02795 "sender='org.freedesktop.Hal'", error);
02796 if (dbus_error_is_set (error)) {
02797 return FALSE;
02798 }
02799 return TRUE;
02800 }
02801
02802
02815 dbus_bool_t
02816 libhal_device_add_property_watch (LibHalContext *ctx, const char *udi, DBusError *error)
02817 {
02818 char buf[512];
02819
02820 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
02821
02822 snprintf (buf, 512,
02823 "type='signal',"
02824 "interface='org.freedesktop.Hal.Device',"
02825 "sender='org.freedesktop.Hal'," "path=%s", udi);
02826
02827 dbus_bus_add_match (ctx->connection, buf, error);
02828 if (dbus_error_is_set (error)) {
02829 return FALSE;
02830 }
02831 return TRUE;
02832 }
02833
02834
02843 dbus_bool_t
02844 libhal_device_remove_property_watch (LibHalContext *ctx, const char *udi, DBusError *error)
02845 {
02846 char buf[512];
02847
02848 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
02849
02850 snprintf (buf, 512,
02851 "type='signal',"
02852 "interface='org.freedesktop.Hal.Device',"
02853 "sender='org.freedesktop.Hal'," "path=%s", udi);
02854
02855 dbus_bus_remove_match (ctx->connection, buf, error);
02856 if (dbus_error_is_set (error)) {
02857 return FALSE;
02858 }
02859 return TRUE;
02860 }
02861
02862
02867 LibHalContext *
02868 libhal_ctx_new (void)
02869 {
02870 LibHalContext *ctx;
02871
02872 if (!libhal_already_initialized_once) {
02873 bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
02874 bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
02875
02876 libhal_already_initialized_once = TRUE;
02877 }
02878
02879 ctx = calloc (1, sizeof (LibHalContext));
02880 if (ctx == NULL) {
02881 fprintf (stderr,
02882 "%s %d : Failed to allocate %d bytes\n",
02883 __FILE__, __LINE__, sizeof (LibHalContext));
02884 return NULL;
02885 }
02886
02887 ctx->is_initialized = FALSE;
02888 ctx->is_shutdown = FALSE;
02889 ctx->connection = NULL;
02890 ctx->is_direct = FALSE;
02891
02892 return ctx;
02893 }
02894
02904 dbus_bool_t
02905 libhal_ctx_set_cache (LibHalContext *ctx, dbus_bool_t use_cache)
02906 {
02907 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
02908
02909 ctx->cache_enabled = use_cache;
02910 return TRUE;
02911 }
02912
02920 dbus_bool_t
02921 libhal_ctx_set_dbus_connection (LibHalContext *ctx, DBusConnection *conn)
02922 {
02923 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
02924
02925 if (conn == NULL)
02926 return FALSE;
02927
02928 ctx->connection = conn;
02929 return TRUE;
02930 }
02931
02940 dbus_bool_t
02941 libhal_ctx_init (LibHalContext *ctx, DBusError *error)
02942 {
02943 DBusError _error;
02944 dbus_bool_t hald_exists;
02945
02946 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
02947
02948 if (ctx->connection == NULL)
02949 return FALSE;
02950
02951 dbus_error_init (&_error);
02952 hald_exists = dbus_bus_name_has_owner (ctx->connection, "org.freedesktop.Hal", &_error);
02953 dbus_move_error (&_error, error);
02954 if (error != NULL && dbus_error_is_set (error)) {
02955 return FALSE;
02956 }
02957
02958 if (!hald_exists) {
02959 return FALSE;
02960 }
02961
02962
02963 if (!dbus_connection_add_filter (ctx->connection, filter_func, ctx, NULL)) {
02964 return FALSE;
02965 }
02966
02967 dbus_bus_add_match (ctx->connection,
02968 "type='signal',"
02969 "interface='org.freedesktop.Hal.Manager',"
02970 "sender='org.freedesktop.Hal',"
02971 "path='/org/freedesktop/Hal/Manager'", &_error);
02972 dbus_move_error (&_error, error);
02973 if (error != NULL && dbus_error_is_set (error)) {
02974 return FALSE;
02975 }
02976 ctx->is_initialized = TRUE;
02977 ctx->is_direct = FALSE;
02978
02979 return TRUE;
02980 }
02981
02988 LibHalContext *
02989 libhal_ctx_init_direct (DBusError *error)
02990 {
02991 char *hald_addr;
02992 LibHalContext *ctx;
02993 DBusError _error;
02994
02995 ctx = libhal_ctx_new ();
02996 if (ctx == NULL)
02997 goto out;
02998
02999 if (((hald_addr = getenv ("HALD_DIRECT_ADDR"))) == NULL) {
03000 libhal_ctx_free (ctx);
03001 ctx = NULL;
03002 goto out;
03003 }
03004
03005 dbus_error_init (&_error);
03006 ctx->connection = dbus_connection_open (hald_addr, &_error);
03007 dbus_move_error (&_error, error);
03008 if (error != NULL && dbus_error_is_set (error)) {
03009 libhal_ctx_free (ctx);
03010 ctx = NULL;
03011 goto out;
03012 }
03013
03014 ctx->is_initialized = TRUE;
03015 ctx->is_direct = TRUE;
03016
03017 out:
03018 return ctx;
03019 }
03020
03029 dbus_bool_t
03030 libhal_ctx_shutdown (LibHalContext *ctx, DBusError *error)
03031 {
03032 DBusError myerror;
03033
03034 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
03035
03036 if (ctx->is_direct) {
03037
03038
03039 } else {
03040 dbus_error_init (&myerror);
03041 dbus_bus_remove_match (ctx->connection,
03042 "type='signal',"
03043 "interface='org.freedesktop.Hal.Manager',"
03044 "sender='org.freedesktop.Hal',"
03045 "path='/org/freedesktop/Hal/Manager'", &myerror);
03046 if (dbus_error_is_set (&myerror)) {
03047 dbus_move_error (&myerror, error);
03048 fprintf (stderr, "%s %d : Error unsubscribing to signals, error=%s\n",
03049 __FILE__, __LINE__, error->message);
03051 }
03052
03053
03054
03055 dbus_connection_remove_filter (ctx->connection, filter_func, ctx);
03056 }
03057
03058 ctx->is_initialized = FALSE;
03059
03060 return TRUE;
03061 }
03062
03068 dbus_bool_t
03069 libhal_ctx_free (LibHalContext *ctx)
03070 {
03071 free (ctx);
03072 return TRUE;
03073 }
03074
03082 dbus_bool_t
03083 libhal_ctx_set_device_added (LibHalContext *ctx, LibHalDeviceAdded callback)
03084 {
03085 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
03086
03087 ctx->device_added = callback;
03088 return TRUE;
03089 }
03090
03098 dbus_bool_t
03099 libhal_ctx_set_device_removed (LibHalContext *ctx, LibHalDeviceRemoved callback)
03100 {
03101 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
03102
03103 ctx->device_removed = callback;
03104 return TRUE;
03105 }
03106
03115 dbus_bool_t
03116 libhal_ctx_set_device_new_capability (LibHalContext *ctx, LibHalDeviceNewCapability callback)
03117 {
03118 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
03119
03120 ctx->device_new_capability = callback;
03121 return TRUE;
03122 }
03123
03132 dbus_bool_t
03133 libhal_ctx_set_device_lost_capability (LibHalContext *ctx, LibHalDeviceLostCapability callback)
03134 {
03135 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
03136
03137 ctx->device_lost_capability = callback;
03138 return TRUE;
03139 }
03140
03149 dbus_bool_t
03150 libhal_ctx_set_device_property_modified (LibHalContext *ctx, LibHalDevicePropertyModified callback)
03151 {
03152 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
03153
03154 ctx->device_property_modified = callback;
03155 return TRUE;
03156 }
03157
03165 dbus_bool_t
03166 libhal_ctx_set_device_condition (LibHalContext *ctx, LibHalDeviceCondition callback)
03167 {
03168 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
03169
03170 ctx->device_condition = callback;
03171 return TRUE;
03172 }
03173
03179 unsigned int libhal_string_array_length (char **str_array)
03180 {
03181 unsigned int i;
03182
03183 if (str_array == NULL)
03184 return 0;
03185
03186 for (i = 0; str_array[i] != NULL; i++)
03187 ;
03188
03189 return i;
03190 }
03191
03192
03193 dbus_bool_t
03194 libhal_device_rescan (LibHalContext *ctx, const char *udi, DBusError *error)
03195 {
03196 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
03197
03198 DBusMessage *message;
03199 DBusMessageIter reply_iter;
03200 DBusMessage *reply;
03201 dbus_bool_t result;
03202
03203 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
03204 "org.freedesktop.Hal.Device",
03205 "Rescan");
03206
03207 if (message == NULL) {
03208 fprintf (stderr,
03209 "%s %d : Couldn't allocate D-BUS message\n",
03210 __FILE__, __LINE__);
03211 return FALSE;
03212 }
03213
03214 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
03215 message, -1,
03216 error);
03217
03218 if (dbus_error_is_set (error)) {
03219 dbus_message_unref (message);
03220 return FALSE;
03221 }
03222
03223 dbus_message_unref (message);
03224
03225 if (reply == NULL)
03226 return FALSE;
03227
03228 dbus_message_iter_init (reply, &reply_iter);
03229 if (dbus_message_iter_get_arg_type (&reply_iter) !=
03230 DBUS_TYPE_BOOLEAN) {
03231 dbus_message_unref (message);
03232 dbus_message_unref (reply);
03233 return FALSE;
03234 }
03235 dbus_message_iter_get_basic (&reply_iter, &result);
03236
03237 dbus_message_unref (reply);
03238
03239 return result;
03240 }
03241
03242 dbus_bool_t
03243 libhal_device_reprobe (LibHalContext *ctx, const char *udi, DBusError *error)
03244 {
03245 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
03246
03247 DBusMessage *message;
03248 DBusMessageIter reply_iter;
03249 DBusMessage *reply;
03250 dbus_bool_t result;
03251
03252 message = dbus_message_new_method_call ("org.freedesktop.Hal",
03253 udi,
03254 "org.freedesktop.Hal.Device",
03255 "Reprobe");
03256
03257 if (message == NULL) {
03258 fprintf (stderr,
03259 "%s %d : Couldn't allocate D-BUS message\n",
03260 __FILE__, __LINE__);
03261 return FALSE;
03262 }
03263
03264 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
03265 message, -1,
03266 error);
03267
03268 if (dbus_error_is_set (error)) {
03269 dbus_message_unref (message);
03270 return FALSE;
03271 }
03272
03273 dbus_message_unref (message);
03274
03275 if (reply == NULL)
03276 return FALSE;
03277
03278 dbus_message_iter_init (reply, &reply_iter);
03279 if (dbus_message_iter_get_arg_type (&reply_iter) !=
03280 DBUS_TYPE_BOOLEAN) {
03281 dbus_message_unref (message);
03282 dbus_message_unref (reply);
03283 return FALSE;
03284 }
03285 dbus_message_iter_get_basic (&reply_iter, &result);
03286
03287 dbus_message_unref (reply);
03288
03289 return result;
03290 }
03291
03303 dbus_bool_t libhal_device_emit_condition (LibHalContext *ctx,
03304 const char *udi,
03305 const char *condition_name,
03306 const char *condition_details,
03307 DBusError *error)
03308 {
03309 LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
03310
03311 DBusMessage *message;
03312 DBusMessageIter iter;
03313 DBusMessageIter reply_iter;
03314 DBusMessage *reply;
03315 dbus_bool_t result;
03316
03317 message = dbus_message_new_method_call ("org.freedesktop.Hal",
03318 udi,
03319 "org.freedesktop.Hal.Device",
03320 "EmitCondition");
03321
03322 if (message == NULL) {
03323 fprintf (stderr,
03324 "%s %d : Couldn't allocate D-BUS message\n",
03325 __FILE__, __LINE__);
03326 return FALSE;
03327 }
03328
03329 dbus_message_iter_init_append (message, &iter);
03330 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &condition_name);
03331 dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &condition_details);
03332
03333 reply = dbus_connection_send_with_reply_and_block (ctx->connection,
03334 message, -1,
03335 error);
03336
03337 if (dbus_error_is_set (error)) {
03338 dbus_message_unref (message);
03339 return FALSE;
03340 }
03341
03342 dbus_message_unref (message);
03343
03344 if (reply == NULL)
03345 return FALSE;
03346
03347 dbus_message_iter_init (reply, &reply_iter);
03348 if (dbus_message_iter_get_arg_type (&reply_iter) !=
03349 DBUS_TYPE_BOOLEAN) {
03350 dbus_message_unref (message);
03351 dbus_message_unref (reply);
03352 return FALSE;
03353 }
03354 dbus_message_iter_get_basic (&reply_iter, &result);
03355
03356 dbus_message_unref (reply);
03357
03358 return result;
03359 }
03360