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

libhal.c

00001 /*************************************************************************** 00002 * CVSID: $Id: libhal.c,v 1.24 2004/08/04 15:35:17 david Exp $ 00003 * 00004 * libhal.c : HAL daemon C convenience library 00005 * 00006 * Copyright (C) 2003 David Zeuthen, <david@fubar.dk> 00007 * 00008 * Licensed under the Academic Free License version 2.0 00009 * 00010 * This program is free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; either version 2 of the License, or 00013 * (at your option) any later version. 00014 * 00015 * This program is distributed in the hope that it will be useful, 00016 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 * GNU General Public License for more details. 00019 * 00020 * You should have received a copy of the GNU General Public License 00021 * along with this program; if not, write to the Free Software 00022 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00023 * 00024 **************************************************************************/ 00025 00026 #ifdef HAVE_CONFIG_H 00027 # include <config.h> 00028 #endif 00029 00030 #include <stdio.h> 00031 #include <stdlib.h> 00032 #include <string.h> 00033 #include <dbus/dbus.h> 00034 00035 #include "libhal.h" 00036 00049 void 00050 hal_free_string_array (char **str_array) 00051 { 00052 if (str_array != NULL) { 00053 int i; 00054 00055 for (i = 0; str_array[i] != NULL; i++) { 00056 free (str_array[i]); 00057 } 00058 free (str_array); 00059 } 00060 } 00061 00066 void 00067 hal_free_string (char *str) 00068 { 00070 free (str); 00071 } 00072 00073 00075 struct LibHalPropertySet_s { 00076 unsigned int num_properties; 00077 LibHalProperty *properties_head; 00080 }; 00081 00083 struct LibHalProperty_s { 00084 int type; 00085 char *key; 00088 union { 00089 char *str_value; 00090 dbus_int32_t int_value; 00092 double double_value; 00093 dbus_bool_t bool_value; 00095 }; 00096 00097 LibHalProperty *next; 00099 }; 00100 00102 struct LibHalContext_s { 00103 DBusConnection *connection; 00104 dbus_bool_t is_initialized; 00105 dbus_bool_t cache_enabled; 00106 const LibHalFunctions *functions; 00107 void *user_data; 00108 }; 00109 00115 void 00116 hal_ctx_set_user_data(LibHalContext *ctx, void *user_data) 00117 { 00118 ctx->user_data = user_data; 00119 } 00120 00127 void* 00128 hal_ctx_get_user_data(LibHalContext *ctx) 00129 { 00130 return ctx->user_data; 00131 } 00132 00133 00141 LibHalPropertySet * 00142 hal_device_get_all_properties (LibHalContext *ctx, const char *udi) 00143 { 00144 DBusError error; 00145 DBusMessage *message; 00146 DBusMessage *reply; 00147 DBusMessageIter iter; 00148 DBusMessageIter dict_iter; 00149 LibHalPropertySet *result; 00150 LibHalProperty **pn; 00151 00152 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, 00153 "org.freedesktop.Hal.Device", 00154 "GetAllProperties"); 00155 if (message == NULL) { 00156 fprintf (stderr, 00157 "%s %d : Couldn't allocate D-BUS message\n", 00158 __FILE__, __LINE__); 00159 return NULL; 00160 } 00161 00162 dbus_error_init (&error); 00163 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 00164 message, -1, 00165 &error); 00166 if (dbus_error_is_set (&error)) { 00167 fprintf (stderr, "%s %d: %s raised\n\"%s\"\n\n", __FILE__, 00168 __LINE__, error.name, error.message); 00169 dbus_message_unref (message); 00170 return NULL; 00171 } 00172 00173 if (reply == NULL) { 00174 dbus_message_unref (message); 00175 return NULL; 00176 } 00177 00178 dbus_message_iter_init (reply, &iter); 00179 00180 result = malloc (sizeof (LibHalPropertySet)); 00181 if (result == NULL) { 00182 fprintf (stderr, "%s %d : error allocating memory\n", 00183 __FILE__, __LINE__); 00184 dbus_message_unref (message); 00185 dbus_message_unref (reply); 00186 return NULL; 00187 } 00188 00189 /* 00190 result->properties = malloc(sizeof(LibHalProperty)*result->num_properties); 00191 if( result->properties==NULL ) 00192 { 00194 return NULL; 00195 } 00196 */ 00197 00198 pn = &result->properties_head; 00199 result->num_properties = 0; 00200 00201 dbus_message_iter_init_dict_iterator (&iter, &dict_iter); 00202 00203 do { 00204 char *dbus_str; 00205 LibHalProperty *p; 00206 00207 p = malloc (sizeof (LibHalProperty)); 00208 if (p == NULL) { 00209 fprintf (stderr, 00210 "%s %d : error allocating memory\n", 00211 __FILE__, __LINE__); 00213 return NULL; 00214 } 00215 00216 *pn = p; 00217 pn = &p->next; 00218 p->next = NULL; 00219 result->num_properties++; 00220 00221 dbus_str = dbus_message_iter_get_dict_key (&dict_iter); 00222 p->key = 00223 (char *) ((dbus_str != NULL) ? strdup (dbus_str) : 00224 NULL); 00225 if (p->key == NULL) { 00226 fprintf (stderr, 00227 "%s %d : error allocating memory\n", 00228 __FILE__, __LINE__); 00230 return NULL; 00231 } 00232 dbus_free (dbus_str); 00233 00234 p->type = dbus_message_iter_get_arg_type (&dict_iter); 00235 00236 switch (p->type) { 00237 case DBUS_TYPE_STRING: 00238 dbus_str = 00239 dbus_message_iter_get_string (&dict_iter); 00240 p->str_value = 00241 (char *) ((dbus_str != NULL) ? 00242 strdup (dbus_str) : NULL); 00243 if (p->str_value == NULL) { 00244 fprintf (stderr, 00245 "%s %d : error allocating memory\n", 00246 __FILE__, __LINE__); 00248 return NULL; 00249 } 00250 dbus_free (dbus_str); 00251 break; 00252 case DBUS_TYPE_INT32: 00253 p->int_value = 00254 dbus_message_iter_get_int32 (&dict_iter); 00255 break; 00256 case DBUS_TYPE_DOUBLE: 00257 p->double_value = 00258 dbus_message_iter_get_double (&dict_iter); 00259 break; 00260 case DBUS_TYPE_BOOLEAN: 00261 p->bool_value = 00262 dbus_message_iter_get_boolean (&dict_iter); 00263 break; 00264 00265 default: 00267 break; 00268 } 00269 00270 } 00271 while (dbus_message_iter_has_next (&dict_iter) && 00272 dbus_message_iter_next (&dict_iter)); 00273 00274 dbus_message_unref (message); 00275 dbus_message_unref (reply); 00276 00277 return result; 00278 } 00279 00284 void 00285 hal_free_property_set (LibHalPropertySet * set) 00286 { 00287 LibHalProperty *p; 00288 LibHalProperty *q; 00289 00290 for (p = set->properties_head; p != NULL; p = q) { 00291 free (p->key); 00292 if (p->type == DBUS_TYPE_STRING) 00293 free (p->str_value); 00294 q = p->next; 00295 free (p); 00296 } 00297 free (set); 00298 } 00299 00305 void 00306 hal_psi_init (LibHalPropertySetIterator * iter, LibHalPropertySet * set) 00307 { 00308 iter->set = set; 00309 iter->index = 0; 00310 iter->cur_prop = set->properties_head; 00311 } 00312 00318 dbus_bool_t 00319 hal_psi_has_more (LibHalPropertySetIterator * iter) 00320 { 00321 return iter->index < iter->set->num_properties; 00322 } 00323 00328 void 00329 hal_psi_next (LibHalPropertySetIterator * iter) 00330 { 00331 iter->index++; 00332 iter->cur_prop = iter->cur_prop->next; 00333 } 00334 00341 int 00342 hal_psi_get_type (LibHalPropertySetIterator * iter) 00343 { 00344 return iter->cur_prop->type; 00345 } 00346 00355 char * 00356 hal_psi_get_key (LibHalPropertySetIterator * iter) 00357 { 00358 return iter->cur_prop->key; 00359 } 00360 00369 char * 00370 hal_psi_get_string (LibHalPropertySetIterator * iter) 00371 { 00372 return iter->cur_prop->str_value; 00373 } 00374 00380 dbus_int32_t 00381 hal_psi_get_int (LibHalPropertySetIterator * iter) 00382 { 00383 return iter->cur_prop->int_value; 00384 } 00385 00391 double 00392 hal_psi_get_double (LibHalPropertySetIterator * iter) 00393 { 00394 return iter->cur_prop->double_value; 00395 } 00396 00402 dbus_bool_t 00403 hal_psi_get_bool (LibHalPropertySetIterator * iter) 00404 { 00405 return iter->cur_prop->bool_value; 00406 } 00407 00408 00409 #ifndef DOXYGEN_SHOULD_SKIP_THIS 00410 static DBusHandlerResult 00411 filter_func (DBusConnection * connection, 00412 DBusMessage * message, void *user_data) 00413 { 00414 const char *object_path; 00415 DBusError error; 00416 LibHalContext *ctx = (LibHalContext *) user_data; 00417 00418 dbus_error_init (&error); 00419 00420 object_path = dbus_message_get_path (message); 00421 00422 /*printf("*** in filter_func, object_path=%s\n", object_path); */ 00423 00424 if (dbus_message_is_signal (message, "org.freedesktop.Hal.Manager", 00425 "DeviceAdded")) { 00426 char *udi; 00427 if (dbus_message_get_args (message, &error, 00428 DBUS_TYPE_STRING, &udi, 00429 DBUS_TYPE_INVALID)) { 00430 if (ctx->functions->device_added != NULL) { 00431 ctx->functions->device_added (ctx, udi); 00432 } 00433 dbus_free (udi); 00434 } 00435 return DBUS_HANDLER_RESULT_HANDLED; 00436 } else 00437 if (dbus_message_is_signal 00438 (message, "org.freedesktop.Hal.Manager", 00439 "DeviceRemoved")) { 00440 char *udi; 00441 if (dbus_message_get_args (message, &error, 00442 DBUS_TYPE_STRING, &udi, 00443 DBUS_TYPE_INVALID)) { 00444 if (ctx->functions->device_removed != NULL) { 00445 ctx->functions->device_removed (ctx, udi); 00446 } 00447 dbus_free (udi); 00448 } 00449 return DBUS_HANDLER_RESULT_HANDLED; 00450 } else 00451 if (dbus_message_is_signal 00452 (message, "org.freedesktop.Hal.Manager", 00453 "NewCapability")) { 00454 char *udi; 00455 char *capability; 00456 if (dbus_message_get_args (message, &error, 00457 DBUS_TYPE_STRING, &udi, 00458 DBUS_TYPE_STRING, &capability, 00459 DBUS_TYPE_INVALID)) { 00460 if (ctx->functions->device_new_capability != NULL) { 00461 ctx->functions->device_new_capability (ctx, 00462 udi, 00463 capability); 00464 } 00465 dbus_free (udi); 00466 dbus_free (capability); 00467 } 00468 return DBUS_HANDLER_RESULT_HANDLED; 00469 } else 00470 if (dbus_message_is_signal 00471 (message, "org.freedesktop.Hal.Device", "Condition")) { 00472 if (ctx->functions->device_condition != NULL) { 00473 DBusMessageIter iter; 00474 char *condition_name; 00475 00476 dbus_message_iter_init (message, &iter); 00477 condition_name = 00478 dbus_message_iter_get_string (&iter); 00479 00480 ctx->functions->device_condition (ctx, 00481 object_path, 00482 condition_name, 00483 message); 00484 00485 dbus_free (condition_name); 00486 } 00487 return DBUS_HANDLER_RESULT_HANDLED; 00488 } else 00489 if (dbus_message_is_signal 00490 (message, "org.freedesktop.Hal.Device", 00491 "PropertyModified")) { 00492 if (ctx->functions->device_property_modified != NULL) { 00493 int i; 00494 char *key; 00495 dbus_bool_t removed, added; 00496 int num_modifications; 00497 DBusMessageIter iter; 00498 00499 dbus_message_iter_init (message, &iter); 00500 num_modifications = 00501 dbus_message_iter_get_int32 (&iter); 00502 dbus_message_iter_next (&iter); 00503 00504 00505 for (i = 0; i < num_modifications; i++) { 00506 00507 key = dbus_message_iter_get_string (&iter); 00508 dbus_message_iter_next (&iter); 00509 removed = 00510 dbus_message_iter_get_boolean (&iter); 00511 dbus_message_iter_next (&iter); 00512 added = 00513 dbus_message_iter_get_boolean (&iter); 00514 dbus_message_iter_next (&iter); 00515 00516 ctx->functions-> 00517 device_property_modified (ctx, 00518 object_path, 00519 key, removed, 00520 added); 00521 00522 dbus_free (key); 00523 } 00524 00525 } 00526 return DBUS_HANDLER_RESULT_HANDLED; 00527 } 00528 00529 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 00530 } 00531 00532 static LibHalFunctions hal_null_functions = { 00533 NULL /*mainloop_integration */ , 00534 NULL /*device_added */ , 00535 NULL /*device_removed */ , 00536 NULL /*device_new_capability */ , 00537 NULL /*device_lost_capability */ , 00538 NULL /*property_modified */ , 00539 NULL /*device_condition */ 00540 }; 00541 #endif /* DOXYGEN_SHOULD_SKIP_THIS */ 00542 00561 LibHalContext* 00562 hal_initialize (const LibHalFunctions * cb_functions, 00563 dbus_bool_t use_cache) 00564 { 00565 DBusError error; 00566 LibHalContext *ctx; 00567 00568 ctx = malloc (sizeof (LibHalContext)); 00569 if (ctx == NULL) { 00570 fprintf (stderr, "%s %d : Cannot allocated %d bytes!\n", 00571 __FILE__, __LINE__, sizeof (LibHalContext)); 00572 return NULL; 00573 } 00574 00575 ctx->cache_enabled = use_cache; 00576 00577 ctx->functions = cb_functions; 00578 /* allow caller to pass NULL */ 00579 if (ctx->functions == NULL) 00580 ctx->functions = &hal_null_functions; 00581 00582 /* connect to hald service on the system bus */ 00583 dbus_error_init (&error); 00584 ctx->connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error); 00585 if (ctx->connection == NULL) { 00586 fprintf (stderr, 00587 "%s %d : Error connecting to system bus: %s\n", 00588 __FILE__, __LINE__, error.message); 00589 dbus_error_free (&error); 00590 return NULL; 00591 } 00592 00593 if (ctx->functions->main_loop_integration != NULL) { 00594 00595 ctx->functions->main_loop_integration (ctx, ctx->connection); 00596 } 00597 00598 if (!dbus_connection_add_filter 00599 (ctx->connection, filter_func, ctx, NULL)) { 00600 fprintf (stderr, 00601 "%s %d : Error creating connection handler\r\n", 00602 __FILE__, __LINE__); 00604 return NULL; 00605 } 00606 00607 dbus_bus_add_match (ctx->connection, 00608 "type='signal'," 00609 "interface='org.freedesktop.Hal.Manager'," 00610 "sender='org.freedesktop.Hal'," 00611 "path='/org/freedesktop/Hal/Manager'", &error); 00612 if (dbus_error_is_set (&error)) { 00613 fprintf (stderr, "%s %d : Error subscribing to signals, " 00614 "error=%s\r\n", 00615 __FILE__, __LINE__, error.message); 00617 return NULL; 00618 } 00619 00620 ctx->is_initialized = TRUE; 00621 00622 return ctx; 00623 } 00624 00631 int 00632 hal_shutdown (LibHalContext *ctx) 00633 { 00634 if (!ctx->is_initialized) 00635 return 1; 00636 00638 free (ctx); 00639 return 0; 00640 } 00641 00651 char ** 00652 hal_get_all_devices (LibHalContext *ctx, int *num_devices) 00653 { 00654 int i; 00655 DBusError error; 00656 DBusMessage *message; 00657 DBusMessage *reply; 00658 DBusMessageIter iter; 00659 char **device_names; 00660 char **hal_device_names; 00661 00662 message = dbus_message_new_method_call ("org.freedesktop.Hal", 00663 "/org/freedesktop/Hal/Manager", 00664 "org.freedesktop.Hal.Manager", 00665 "GetAllDevices"); 00666 if (message == NULL) { 00667 fprintf (stderr, 00668 "%s %d : Couldn't allocate D-BUS message\n", 00669 __FILE__, __LINE__); 00670 return NULL; 00671 } 00672 00673 dbus_error_init (&error); 00674 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 00675 message, -1, 00676 &error); 00677 if (dbus_error_is_set (&error)) { 00678 fprintf (stderr, "%s %d : %s raised\n\"%s\"\n\n", __FILE__, 00679 __LINE__, error.name, error.message); 00680 dbus_message_unref (message); 00681 return NULL; 00682 } 00683 00684 if (reply == NULL) { 00685 dbus_message_unref (message); 00686 return NULL; 00687 } 00688 00689 /* now analyze reply */ 00690 dbus_message_iter_init (reply, &iter); 00691 if (!dbus_message_iter_get_string_array (&iter, 00692 &device_names, 00693 num_devices)) { 00694 fprintf (stderr, "%s %d : wrong reply from hald\n", 00695 __FILE__, __LINE__); 00696 return NULL; 00697 } 00698 00699 dbus_message_unref (reply); 00700 dbus_message_unref (message); 00701 00702 /* Have to convert from dbus string array to hal string array 00703 * since we can't poke at the dbus string array for the reason 00704 * that d-bus use their own memory allocation scheme 00705 */ 00706 hal_device_names = malloc (sizeof (char *) * ((*num_devices) + 1)); 00707 if (hal_device_names == NULL) 00708 return NULL; 00711 for (i = 0; i < (*num_devices); i++) { 00712 hal_device_names[i] = strdup (device_names[i]); 00713 if (hal_device_names[i] == NULL) { 00714 fprintf (stderr, 00715 "%s %d : error allocating memory\n", 00716 __FILE__, __LINE__); 00718 return NULL; 00719 } 00720 } 00721 hal_device_names[i] = NULL; 00722 00723 dbus_free_string_array (device_names); 00724 00725 return hal_device_names; 00726 } 00727 00737 int 00738 hal_device_get_property_type (LibHalContext *ctx, 00739 const char *udi, const char *key) 00740 { 00741 DBusError error; 00742 DBusMessage *message; 00743 DBusMessage *reply; 00744 DBusMessageIter iter; 00745 int type; 00746 00747 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, 00748 "org.freedesktop.Hal.Device", 00749 "GetPropertyType"); 00750 if (message == NULL) { 00751 fprintf (stderr, 00752 "%s %d : Couldn't allocate D-BUS message\n", 00753 __FILE__, __LINE__); 00754 return DBUS_TYPE_NIL; 00755 } 00756 00757 dbus_message_iter_init (message, &iter); 00758 dbus_message_iter_append_string (&iter, key); 00759 dbus_error_init (&error); 00760 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 00761 message, -1, 00762 &error); 00763 if (dbus_error_is_set (&error)) { 00764 fprintf (stderr, "%s %d : %s raised\n\"%s\"\n\n", __FILE__, 00765 __LINE__, error.name, error.message); 00766 dbus_message_unref (message); 00767 return DBUS_TYPE_NIL; 00768 } 00769 if (reply == NULL) { 00770 dbus_message_unref (message); 00771 return DBUS_TYPE_NIL; 00772 } 00773 00774 dbus_message_iter_init (reply, &iter); 00775 type = dbus_message_iter_get_int32 (&iter); 00776 00777 dbus_message_unref (message); 00778 dbus_message_unref (reply); 00779 00780 return type; 00781 } 00782 00794 char * 00795 hal_device_get_property_string (LibHalContext *ctx, 00796 const char *udi, const char *key) 00797 { 00798 DBusError error; 00799 DBusMessage *message; 00800 DBusMessage *reply; 00801 DBusMessageIter iter; 00802 char *value; 00803 char *dbus_str; 00804 00805 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, 00806 "org.freedesktop.Hal.Device", 00807 "GetPropertyString"); 00808 if (message == NULL) { 00809 fprintf (stderr, 00810 "%s %d : Couldn't allocate D-BUS message\n", 00811 __FILE__, __LINE__); 00812 return NULL; 00813 } 00814 00815 dbus_message_iter_init (message, &iter); 00816 dbus_message_iter_append_string (&iter, key); 00817 dbus_error_init (&error); 00818 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 00819 message, -1, 00820 &error); 00821 if (dbus_error_is_set (&error)) { 00822 fprintf (stderr, "%s %d : Error sending msg: %s\n", 00823 __FILE__, __LINE__, error.message); 00824 dbus_message_unref (message); 00825 return NULL; 00826 } 00827 if (reply == NULL) { 00828 dbus_message_unref (message); 00829 return NULL; 00830 } 00831 00832 dbus_message_iter_init (reply, &iter); 00833 00834 /* now analyze reply */ 00835 if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_NIL) { 00836 fprintf (stderr, 00837 "%s %d : property '%s' for device '%s' does not " 00838 "exist\n", __FILE__, __LINE__, key, udi); 00839 dbus_message_unref (message); 00840 dbus_message_unref (reply); 00841 return NULL; 00842 } else if (dbus_message_iter_get_arg_type (&iter) != 00843 DBUS_TYPE_STRING) { 00844 fprintf (stderr, 00845 "%s %d : property '%s' for device '%s' is not " 00846 "of type string\n", __FILE__, __LINE__, key, udi); 00847 dbus_message_unref (message); 00848 dbus_message_unref (reply); 00849 return NULL; 00850 } 00851 00852 dbus_str = dbus_message_iter_get_string (&iter); 00853 value = (char *) ((dbus_str != NULL) ? strdup (dbus_str) : NULL); 00854 if (value == NULL) { 00855 fprintf (stderr, "%s %d : error allocating memory\n", 00856 __FILE__, __LINE__); 00858 return NULL; 00859 } 00860 dbus_free (dbus_str); 00861 00862 dbus_message_unref (message); 00863 dbus_message_unref (reply); 00864 return value; 00865 } 00866 00874 dbus_int32_t 00875 hal_device_get_property_int (LibHalContext *ctx, 00876 const char *udi, const char *key) 00877 { 00878 DBusError error; 00879 DBusMessage *message; 00880 DBusMessage *reply; 00881 DBusMessageIter iter; 00882 dbus_int32_t value; 00883 00884 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, 00885 "org.freedesktop.Hal.Device", 00886 "GetPropertyInteger"); 00887 if (message == NULL) { 00888 fprintf (stderr, 00889 "%s %d : Couldn't allocate D-BUS message\n", 00890 __FILE__, __LINE__); 00891 return -1; 00892 } 00893 00894 dbus_message_iter_init (message, &iter); 00895 dbus_message_iter_append_string (&iter, key); 00896 dbus_error_init (&error); 00897 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 00898 message, -1, 00899 &error); 00900 if (dbus_error_is_set (&error)) { 00901 fprintf (stderr, "%s %d : Error sending msg: %s\n", 00902 __FILE__, __LINE__, error.message); 00903 dbus_message_unref (message); 00904 return -1; 00905 } 00906 if (reply == NULL) { 00907 dbus_message_unref (message); 00908 return -1; 00909 } 00910 00911 dbus_message_iter_init (reply, &iter); 00912 00913 /* now analyze reply */ 00914 if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_NIL) { 00915 /* property didn't exist */ 00916 fprintf (stderr, 00917 "%s %d : property '%s' for device '%s' does not " 00918 "exist\n", __FILE__, __LINE__, key, udi); 00919 dbus_message_unref (message); 00920 dbus_message_unref (reply); 00921 return -1; 00922 } else if (dbus_message_iter_get_arg_type (&iter) != 00923 DBUS_TYPE_INT32) { 00924 fprintf (stderr, 00925 "%s %d : property '%s' for device '%s' is not " 00926 "of type integer\n", __FILE__, __LINE__, key, 00927 udi); 00928 dbus_message_unref (message); 00929 dbus_message_unref (reply); 00930 return -1; 00931 } 00932 value = dbus_message_iter_get_int32 (&iter); 00933 00934 dbus_message_unref (message); 00935 dbus_message_unref (reply); 00936 return value; 00937 } 00938 00946 double 00947 hal_device_get_property_double (LibHalContext *ctx, 00948 const char *udi, const char *key) 00949 { 00950 DBusError error; 00951 DBusMessage *message; 00952 DBusMessage *reply; 00953 DBusMessageIter iter; 00954 double value; 00955 00956 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, 00957 "org.freedesktop.Hal.Device", 00958 "GetPropertyDouble"); 00959 if (message == NULL) { 00960 fprintf (stderr, 00961 "%s %d : Couldn't allocate D-BUS message\n", 00962 __FILE__, __LINE__); 00963 return -1.0f; 00964 } 00965 00966 dbus_message_iter_init (message, &iter); 00967 dbus_message_iter_append_string (&iter, key); 00968 dbus_error_init (&error); 00969 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 00970 message, -1, 00971 &error); 00972 if (dbus_error_is_set (&error)) { 00973 fprintf (stderr, "%s %d : Error sending msg: %s\n", 00974 __FILE__, __LINE__, error.message); 00975 dbus_message_unref (message); 00976 return -1.0f; 00977 } 00978 if (reply == NULL) { 00979 dbus_message_unref (message); 00980 return -1.0f; 00981 } 00982 00983 dbus_message_iter_init (reply, &iter); 00984 00985 /* now analyze reply */ 00986 if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_NIL) { 00987 /* property didn't exist */ 00988 fprintf (stderr, 00989 "%s %d : property '%s' for device '%s' does not " 00990 "exist\n", __FILE__, __LINE__, key, udi); 00991 dbus_message_unref (message); 00992 dbus_message_unref (reply); 00993 return -1.0f; 00994 } else if (dbus_message_iter_get_arg_type (&iter) != 00995 DBUS_TYPE_DOUBLE) { 00996 fprintf (stderr, 00997 "%s %d : property '%s' for device '%s' is not " 00998 "of type double\n", __FILE__, __LINE__, key, udi); 00999 dbus_message_unref (message); 01000 dbus_message_unref (reply); 01001 return -1.0f; 01002 } 01003 value = dbus_message_iter_get_double (&iter); 01004 01005 dbus_message_unref (message); 01006 dbus_message_unref (reply); 01007 return (double) value; 01008 } 01009 01017 dbus_bool_t 01018 hal_device_get_property_bool (LibHalContext *ctx, 01019 const char *udi, const char *key) 01020 { 01021 DBusError error; 01022 DBusMessage *message; 01023 DBusMessage *reply; 01024 DBusMessageIter iter; 01025 double value; 01026 01027 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, 01028 "org.freedesktop.Hal.Device", 01029 "GetPropertyBoolean"); 01030 if (message == NULL) { 01031 fprintf (stderr, 01032 "%s %d : Couldn't allocate D-BUS message\n", 01033 __FILE__, __LINE__); 01034 return FALSE; 01035 } 01036 01037 dbus_message_iter_init (message, &iter); 01038 dbus_message_iter_append_string (&iter, key); 01039 dbus_error_init (&error); 01040 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 01041 message, -1, 01042 &error); 01043 if (dbus_error_is_set (&error)) { 01044 fprintf (stderr, "%s %d : Error sending msg: %s\n", 01045 __FILE__, __LINE__, error.message); 01046 dbus_message_unref (message); 01047 return FALSE; 01048 } 01049 if (reply == NULL) { 01050 dbus_message_unref (message); 01051 return FALSE; 01052 } 01053 01054 dbus_message_iter_init (reply, &iter); 01055 01056 /* now analyze reply */ 01057 if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_NIL) { 01058 /* property didn't exist */ 01059 fprintf (stderr, 01060 "%s %d : property '%s' for device '%s' does not " 01061 "exist\n", __FILE__, __LINE__, key, udi); 01062 dbus_message_unref (message); 01063 dbus_message_unref (reply); 01064 return FALSE; 01065 } else if (dbus_message_iter_get_arg_type (&iter) != 01066 DBUS_TYPE_BOOLEAN) { 01067 fprintf (stderr, 01068 "%s %d : property '%s' for device '%s' is not " 01069 "of type bool\n", __FILE__, __LINE__, key, udi); 01070 dbus_message_unref (message); 01071 dbus_message_unref (reply); 01072 return FALSE; 01073 } 01074 value = dbus_message_iter_get_boolean (&iter); 01075 01076 dbus_message_unref (message); 01077 dbus_message_unref (reply); 01078 return value; 01079 } 01080 01081 01082 /* generic helper */ 01083 static int 01084 hal_device_set_property_helper (LibHalContext *ctx, 01085 const char *udi, 01086 const char *key, 01087 int type, 01088 const char *str_value, 01089 dbus_int32_t int_value, 01090 double double_value, 01091 dbus_bool_t bool_value) 01092 { 01093 DBusError error; 01094 DBusMessage *message; 01095 DBusMessage *reply; 01096 DBusMessageIter iter; 01097 char *method_name = NULL; 01098 01101 switch (type) { 01102 case DBUS_TYPE_NIL: 01103 method_name = "RemoveProperty"; 01104 break; 01105 case DBUS_TYPE_STRING: 01106 method_name = "SetPropertyString"; 01107 break; 01108 case DBUS_TYPE_INT32: 01109 method_name = "SetPropertyInteger"; 01110 break; 01111 case DBUS_TYPE_DOUBLE: 01112 method_name = "SetPropertyDouble"; 01113 break; 01114 case DBUS_TYPE_BOOLEAN: 01115 method_name = "SetPropertyBoolean"; 01116 break; 01117 01118 default: 01119 /* cannot happen; is not callable from outside this file */ 01120 break; 01121 } 01122 01123 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, 01124 "org.freedesktop.Hal.Device", 01125 method_name); 01126 if (message == NULL) { 01127 fprintf (stderr, 01128 "%s %d : Couldn't allocate D-BUS message\n", 01129 __FILE__, __LINE__); 01130 return FALSE; 01131 } 01132 01133 dbus_message_iter_init (message, &iter); 01134 dbus_message_iter_append_string (&iter, key); 01135 switch (type) { 01136 case DBUS_TYPE_NIL: 01137 dbus_message_iter_append_nil (&iter); 01138 break; 01139 case DBUS_TYPE_STRING: 01140 dbus_message_iter_append_string (&iter, str_value); 01141 break; 01142 case DBUS_TYPE_INT32: 01143 dbus_message_iter_append_int32 (&iter, int_value); 01144 break; 01145 case DBUS_TYPE_DOUBLE: 01146 dbus_message_iter_append_double (&iter, double_value); 01147 break; 01148 case DBUS_TYPE_BOOLEAN: 01149 dbus_message_iter_append_boolean (&iter, bool_value); 01150 break; 01151 } 01152 01153 dbus_error_init (&error); 01154 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 01155 message, -1, 01156 &error); 01157 if (dbus_error_is_set (&error)) { 01158 fprintf (stderr, "%s %d: %s raised\n\"%s\"\n\n", __FILE__, 01159 __LINE__, error.name, error.message); 01160 dbus_message_unref (message); 01161 return FALSE; 01162 } 01163 01164 if (reply == NULL) { 01165 dbus_message_unref (message); 01166 return FALSE; 01167 } 01168 01169 return TRUE; 01170 } 01171 01182 dbus_bool_t 01183 hal_device_set_property_string (LibHalContext *ctx, 01184 const char *udi, 01185 const char *key, const char *value) 01186 { 01187 return hal_device_set_property_helper (ctx, udi, key, 01188 DBUS_TYPE_STRING, 01189 value, 0, 0.0f, FALSE); 01190 } 01191 01202 dbus_bool_t 01203 hal_device_set_property_int (LibHalContext *ctx, const char *udi, 01204 const char *key, dbus_int32_t value) 01205 { 01206 return hal_device_set_property_helper (ctx, udi, key, 01207 DBUS_TYPE_INT32, 01208 NULL, value, 0.0f, FALSE); 01209 } 01210 01221 dbus_bool_t 01222 hal_device_set_property_double (LibHalContext *ctx, const char *udi, 01223 const char *key, double value) 01224 { 01225 return hal_device_set_property_helper (ctx, udi, key, 01226 DBUS_TYPE_DOUBLE, 01227 NULL, 0, value, FALSE); 01228 } 01229 01240 dbus_bool_t 01241 hal_device_set_property_bool (LibHalContext *ctx, const char *udi, 01242 const char *key, dbus_bool_t value) 01243 { 01244 return hal_device_set_property_helper (ctx, udi, key, 01245 DBUS_TYPE_BOOLEAN, 01246 NULL, 0, 0.0f, value); 01247 } 01248 01249 01258 dbus_bool_t 01259 hal_device_remove_property (LibHalContext *ctx, 01260 const char *udi, const char *key) 01261 { 01262 return hal_device_set_property_helper (ctx, udi, key, DBUS_TYPE_NIL, 01263 /* DBUS_TYPE_NIL means remove */ 01264 NULL, 0, 0.0f, FALSE); 01265 } 01266 01267 01279 char * 01280 hal_agent_new_device (LibHalContext *ctx) 01281 { 01282 DBusError error; 01283 DBusMessage *message; 01284 DBusMessage *reply; 01285 DBusMessageIter iter; 01286 char *value; 01287 char *dbus_str; 01288 01289 message = dbus_message_new_method_call ("org.freedesktop.Hal", 01290 "/org/freedesktop/Hal/Manager", 01291 "org.freedesktop.Hal.AgentManager", 01292 "NewDevice"); 01293 if (message == NULL) { 01294 fprintf (stderr, 01295 "%s %d : Couldn't allocate D-BUS message\n", 01296 __FILE__, __LINE__); 01297 return NULL; 01298 } 01299 01300 dbus_error_init (&error); 01301 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 01302 message, -1, 01303 &error); 01304 if (dbus_error_is_set (&error)) { 01305 fprintf (stderr, "%s %d : Error sending msg: %s\n", 01306 __FILE__, __LINE__, error.message); 01307 dbus_message_unref (message); 01308 return NULL; 01309 } 01310 if (reply == NULL) { 01311 dbus_message_unref (message); 01312 return NULL; 01313 } 01314 01315 dbus_message_iter_init (reply, &iter); 01316 01317 /* now analyze reply */ 01318 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING) { 01319 fprintf (stderr, 01320 "%s %d : expected a string in reply to NewDevice\n", 01321 __FILE__, __LINE__); 01322 dbus_message_unref (message); 01323 dbus_message_unref (reply); 01324 return NULL; 01325 } 01326 01327 dbus_str = dbus_message_iter_get_string (&iter); 01328 value = (char *) ((dbus_str != NULL) ? strdup (dbus_str) : NULL); 01329 if (value == NULL) { 01330 fprintf (stderr, "%s %d : error allocating memory\n", 01331 __FILE__, __LINE__); 01333 return NULL; 01334 } 01335 dbus_free (dbus_str); 01336 01337 dbus_message_unref (message); 01338 dbus_message_unref (reply); 01339 return value; 01340 } 01341 01342 01361 dbus_bool_t 01362 hal_agent_commit_to_gdl (LibHalContext *ctx, 01363 const char *temp_udi, const char *udi) 01364 { 01365 DBusError error; 01366 DBusMessage *message; 01367 DBusMessage *reply; 01368 DBusMessageIter iter; 01369 01370 message = dbus_message_new_method_call ("org.freedesktop.Hal", 01371 "/org/freedesktop/Hal/Manager", 01372 "org.freedesktop.Hal.AgentManager", 01373 "CommitToGdl"); 01374 if (message == NULL) { 01375 fprintf (stderr, 01376 "%s %d : Couldn't allocate D-BUS message\n", 01377 __FILE__, __LINE__); 01378 return FALSE; 01379 } 01380 01381 dbus_message_iter_init (message, &iter); 01382 dbus_message_iter_append_string (&iter, temp_udi); 01383 dbus_message_iter_append_string (&iter, udi); 01384 01385 dbus_error_init (&error); 01386 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 01387 message, -1, 01388 &error); 01389 if (dbus_error_is_set (&error)) { 01390 if (dbus_error_has_name 01391 (&error, "org.freedesktop.Hal.UdiInUse")) 01392 return FALSE; 01393 fprintf (stderr, "%s %d : Error sending msg: %s\n", 01394 __FILE__, __LINE__, error.message); 01395 dbus_message_unref (message); 01396 return FALSE; 01397 } 01398 if (reply == NULL) { 01399 dbus_message_unref (message); 01400 return FALSE; 01401 } 01402 01403 dbus_message_unref (message); 01404 dbus_message_unref (reply); 01405 return TRUE; 01406 } 01407 01419 dbus_bool_t 01420 hal_agent_remove_device (LibHalContext *ctx, const char *udi) 01421 { 01422 DBusError error; 01423 DBusMessage *message; 01424 DBusMessage *reply; 01425 DBusMessageIter iter; 01426 01427 message = dbus_message_new_method_call ("org.freedesktop.Hal", 01428 "/org/freedesktop/Hal/Manager", 01429 "org.freedesktop.Hal.AgentManager", 01430 "Remove"); 01431 if (message == NULL) { 01432 fprintf (stderr, 01433 "%s %d : Couldn't allocate D-BUS message\n", 01434 __FILE__, __LINE__); 01435 return FALSE; 01436 } 01437 01438 dbus_message_iter_init (message, &iter); 01439 dbus_message_iter_append_string (&iter, udi); 01440 01441 dbus_error_init (&error); 01442 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 01443 message, -1, 01444 &error); 01445 if (dbus_error_is_set (&error)) { 01446 fprintf (stderr, "%s %d : Error sending msg: %s\n", 01447 __FILE__, __LINE__, error.message); 01448 dbus_message_unref (message); 01449 return FALSE; 01450 } 01451 if (reply == NULL) { 01452 dbus_message_unref (message); 01453 return FALSE; 01454 } 01455 01456 dbus_message_unref (message); 01457 dbus_message_unref (reply); 01458 return TRUE; 01459 } 01460 01467 dbus_bool_t 01468 hal_device_exists (LibHalContext *ctx, const char *udi) 01469 { 01470 DBusError error; 01471 DBusMessage *message; 01472 DBusMessage *reply; 01473 DBusMessageIter iter; 01474 dbus_bool_t value; 01475 01476 message = dbus_message_new_method_call ("org.freedesktop.Hal", 01477 "/org/freedesktop/Hal/Manager", 01478 "org.freedesktop.Hal.Manager", 01479 "DeviceExists"); 01480 if (message == NULL) { 01481 fprintf (stderr, 01482 "%s %d : Couldn't allocate D-BUS message\n", 01483 __FILE__, __LINE__); 01484 return FALSE; 01485 } 01486 01487 dbus_message_iter_init (message, &iter); 01488 dbus_message_iter_append_string (&iter, udi); 01489 01490 dbus_error_init (&error); 01491 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 01492 message, -1, 01493 &error); 01494 if (dbus_error_is_set (&error)) { 01495 fprintf (stderr, "%s %d : Error sending msg: %s\n", 01496 __FILE__, __LINE__, error.message); 01497 dbus_message_unref (message); 01498 return FALSE; 01499 } 01500 if (reply == NULL) { 01501 dbus_message_unref (message); 01502 return FALSE; 01503 } 01504 01505 dbus_message_iter_init (reply, &iter); 01506 01507 /* now analyze reply */ 01508 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_BOOLEAN) { 01509 fprintf (stderr, 01510 "%s %d : expected a bool in reply to DeviceExists\n", 01511 __FILE__, __LINE__); 01512 dbus_message_unref (message); 01513 dbus_message_unref (reply); 01514 return FALSE; 01515 } 01516 01517 value = dbus_message_iter_get_boolean (&iter); 01518 01519 dbus_message_unref (message); 01520 dbus_message_unref (reply); 01521 return value; 01522 } 01523 01531 dbus_bool_t 01532 hal_device_property_exists (LibHalContext *ctx, 01533 const char *udi, const char *key) 01534 { 01535 DBusError error; 01536 DBusMessage *message; 01537 DBusMessage *reply; 01538 DBusMessageIter iter; 01539 dbus_bool_t value; 01540 01541 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, 01542 "org.freedesktop.Hal.Device", 01543 "PropertyExists"); 01544 if (message == NULL) { 01545 fprintf (stderr, 01546 "%s %d : Couldn't allocate D-BUS message\n", 01547 __FILE__, __LINE__); 01548 return FALSE; 01549 } 01550 01551 dbus_message_iter_init (message, &iter); 01552 dbus_message_iter_append_string (&iter, key); 01553 01554 dbus_error_init (&error); 01555 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 01556 message, -1, 01557 &error); 01558 if (dbus_error_is_set (&error)) { 01559 fprintf (stderr, "%s %d : Error sending msg: %s\n", 01560 __FILE__, __LINE__, error.message); 01561 dbus_message_unref (message); 01562 return FALSE; 01563 } 01564 if (reply == NULL) { 01565 dbus_message_unref (message); 01566 return FALSE; 01567 } 01568 01569 dbus_message_iter_init (reply, &iter); 01570 01571 /* now analyse reply */ 01572 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_BOOLEAN) { 01573 fprintf (stderr, "%s %d : expected a bool in reply to " 01574 "PropertyExists\n", __FILE__, __LINE__); 01575 dbus_message_unref (message); 01576 dbus_message_unref (reply); 01577 return FALSE; 01578 } 01579 01580 value = dbus_message_iter_get_boolean (&iter); 01581 01582 dbus_message_unref (message); 01583 dbus_message_unref (reply); 01584 return value; 01585 } 01586 01594 dbus_bool_t 01595 hal_agent_merge_properties (LibHalContext *ctx, 01596 const char *target_udi, const char *source_udi) 01597 { 01598 DBusError error; 01599 DBusMessage *message; 01600 DBusMessage *reply; 01601 DBusMessageIter iter; 01602 01603 message = dbus_message_new_method_call ("org.freedesktop.Hal", 01604 "/org/freedesktop/Hal/Manager", 01605 "org.freedesktop.Hal.AgentManager", 01606 "MergeProperties"); 01607 if (message == NULL) { 01608 fprintf (stderr, 01609 "%s %d : Couldn't allocate D-BUS message\n", 01610 __FILE__, __LINE__); 01611 return FALSE; 01612 } 01613 01614 dbus_message_iter_init (message, &iter); 01615 dbus_message_iter_append_string (&iter, target_udi); 01616 dbus_message_iter_append_string (&iter, source_udi); 01617 01618 dbus_error_init (&error); 01619 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 01620 message, -1, 01621 &error); 01622 if (dbus_error_is_set (&error)) { 01623 if (dbus_error_has_name 01624 (&error, "org.freedesktop.Hal.NoSuchDevice")) 01625 return FALSE; 01626 fprintf (stderr, "%s %d : Error sending msg: %s\n", 01627 __FILE__, __LINE__, error.message); 01628 dbus_message_unref (message); 01629 return FALSE; 01630 } 01631 if (reply == NULL) { 01632 dbus_message_unref (message); 01633 return FALSE; 01634 } 01635 01636 dbus_message_unref (message); 01637 dbus_message_unref (reply); 01638 return TRUE; 01639 } 01640 01660 dbus_bool_t 01661 hal_agent_device_matches (LibHalContext *ctx, 01662 const char *udi1, const char *udi2, 01663 const char *property_namespace) 01664 { 01665 DBusError error; 01666 DBusMessage *message; 01667 DBusMessage *reply; 01668 DBusMessageIter iter; 01669 dbus_bool_t value; 01670 01671 message = dbus_message_new_method_call ("org.freedesktop.Hal", 01672 "/org/freedesktop/Hal/Manager", 01673 "org.freedesktop.Hal.AgentManager", 01674 "DeviceMatches"); 01675 if (message == NULL) { 01676 fprintf (stderr, 01677 "%s %d : Couldn't allocate D-BUS message\n", 01678 __FILE__, __LINE__); 01679 return FALSE; 01680 } 01681 01682 dbus_message_iter_init (message, &iter); 01683 dbus_message_iter_append_string (&iter, udi1); 01684 dbus_message_iter_append_string (&iter, udi2); 01685 dbus_message_iter_append_string (&iter, property_namespace); 01686 01687 dbus_error_init (&error); 01688 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 01689 message, -1, 01690 &error); 01691 if (dbus_error_is_set (&error)) { 01692 fprintf (stderr, "%s %d : Error sending msg: %s\n", 01693 __FILE__, __LINE__, error.message); 01694 dbus_message_unref (message); 01695 return FALSE; 01696 } 01697 if (reply == NULL) { 01698 dbus_message_unref (message); 01699 return FALSE; 01700 } 01701 /* now analyse reply */ 01702 dbus_message_iter_init (reply, &iter); 01703 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_BOOLEAN) { 01704 fprintf (stderr, 01705 "%s %d : expected a bool in reply to DeviceMatches\n", 01706 __FILE__, __LINE__); 01707 dbus_message_unref (message); 01708 dbus_message_unref (reply); 01709 return FALSE; 01710 } 01711 01712 value = dbus_message_iter_get_boolean (&iter); 01713 01714 dbus_message_unref (message); 01715 dbus_message_unref (reply); 01716 return value; 01717 } 01718 01724 void 01725 hal_device_print (LibHalContext *ctx, const char *udi) 01726 { 01727 int type; 01728 char *key; 01729 LibHalPropertySet *pset; 01730 LibHalPropertySetIterator i; 01731 01732 printf ("device_id = %s\n", udi); 01733 01734 pset = hal_device_get_all_properties (ctx, udi); 01735 01736 for (hal_psi_init (&i, pset); hal_psi_has_more (&i); 01737 hal_psi_next (&i)) { 01738 type = hal_psi_get_type (&i); 01739 key = hal_psi_get_key (&i); 01740 switch (type) { 01741 case DBUS_TYPE_STRING: 01742 printf (" %s = %s (string)\n", key, 01743 hal_psi_get_string (&i)); 01744 break; 01745 case DBUS_TYPE_INT32: 01746 printf (" %s = %d = 0x%x (int)\n", key, 01747 hal_psi_get_int (&i), 01748 hal_psi_get_int (&i)); 01749 break; 01750 case DBUS_TYPE_BOOLEAN: 01751 printf (" %s = %s (bool)\n", key, 01752 (hal_psi_get_bool (&i) ? "true" : 01753 "false")); 01754 break; 01755 case DBUS_TYPE_DOUBLE: 01756 printf (" %s = %g (double)\n", key, 01757 hal_psi_get_double (&i)); 01758 break; 01759 default: 01760 printf (" *** unknown type for key %s\n", key); 01761 break; 01762 } 01763 } 01764 hal_free_property_set (pset); 01765 } 01766 01777 char ** 01778 hal_manager_find_device_string_match (LibHalContext *ctx, 01779 const char *key, 01780 const char *value, int *num_devices) 01781 { 01782 int i; 01783 DBusError error; 01784 DBusMessage *message; 01785 DBusMessage *reply; 01786 DBusMessageIter iter; 01787 char **device_names; 01788 char **hal_device_names; 01789 01790 message = dbus_message_new_method_call ("org.freedesktop.Hal", 01791 "/org/freedesktop/Hal/Manager", 01792 "org.freedesktop.Hal.Manager", 01793 "FindDeviceStringMatch"); 01794 if (message == NULL) { 01795 fprintf (stderr, 01796 "%s %d : Couldn't allocate D-BUS message\n", 01797 __FILE__, __LINE__); 01798 return NULL; 01799 } 01800 01801 dbus_message_iter_init (message, &iter); 01802 dbus_message_iter_append_string (&iter, key); 01803 dbus_message_iter_append_string (&iter, value); 01804 01805 dbus_error_init (&error); 01806 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 01807 message, -1, 01808 &error); 01809 if (dbus_error_is_set (&error)) { 01810 fprintf (stderr, "%s %d : Error sending msg: %s\n", 01811 __FILE__, __LINE__, error.message); 01812 dbus_message_unref (message); 01813 return NULL; 01814 } 01815 if (reply == NULL) { 01816 dbus_message_unref (message); 01817 return NULL; 01818 } 01819 /* now analyse reply */ 01820 dbus_message_iter_init (reply, &iter); 01821 if (!dbus_message_iter_get_string_array (&iter, 01822 &device_names, 01823 num_devices)) { 01824 fprintf (stderr, "%s %d : wrong reply from hald\n", 01825 __FILE__, __LINE__); 01826 return NULL; 01827 } 01828 01829 dbus_message_unref (message); 01830 dbus_message_unref (reply); 01831 01832 /* Have to convert from dbus string array to hal string array 01833 * since we can't poke at the dbus string array for the reason 01834 * that d-bus use their own memory allocation scheme 01835 */ 01836 hal_device_names = malloc (sizeof (char *) * ((*num_devices) + 1)); 01837 if (hal_device_names == NULL) 01838 return NULL; 01841 for (i = 0; i < (*num_devices); i++) { 01842 hal_device_names[i] = strdup (device_names[i]); 01843 if (hal_device_names[i] == NULL) 01844 return NULL; 01846 } 01847 hal_device_names[i] = NULL; 01848 01849 dbus_free_string_array (device_names); 01850 01851 return hal_device_names; 01852 } 01853 01854 01863 dbus_bool_t 01864 hal_device_add_capability (LibHalContext *ctx, 01865 const char *udi, const char *capability) 01866 { 01867 DBusError error; 01868 DBusMessage *message; 01869 DBusMessage *reply; 01870 DBusMessageIter iter; 01871 01872 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, 01873 "org.freedesktop.Hal.Device", 01874 "AddCapability"); 01875 if (message == NULL) { 01876 fprintf (stderr, 01877 "%s %d : Couldn't allocate D-BUS message\n", 01878 __FILE__, __LINE__); 01879 return FALSE; 01880 } 01881 01882 dbus_message_iter_init (message, &iter); 01883 dbus_message_iter_append_string (&iter, capability); 01884 01885 dbus_error_init (&error); 01886 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 01887 message, -1, 01888 &error); 01889 if (dbus_error_is_set (&error)) { 01890 fprintf (stderr, "%s %d: %s raised\n\"%s\"\n\n", __FILE__, 01891 __LINE__, error.name, error.message); 01892 dbus_message_unref (message); 01893 return FALSE; 01894 } 01895 01896 if (reply == NULL) { 01897 dbus_message_unref (message); 01898 return FALSE; 01899 } 01900 01901 dbus_message_unref (reply); 01902 dbus_message_unref (message); 01903 return TRUE; 01904 } 01905 01915 dbus_bool_t 01916 hal_device_query_capability (LibHalContext *ctx, 01917 const char *udi, const char *capability) 01918 { 01919 char *caps; 01920 01921 caps = hal_device_get_property_string (ctx, udi, "info.capabilities"); 01922 01923 if (caps != NULL) 01924 if (strstr (caps, capability) != NULL) 01925 return TRUE; 01926 01927 return FALSE; 01928 } 01929 01938 char ** 01939 hal_find_device_by_capability (LibHalContext *ctx, 01940 const char *capability, int *num_devices) 01941 { 01942 int i; 01943 DBusError error; 01944 DBusMessage *message; 01945 DBusMessage *reply; 01946 DBusMessageIter iter; 01947 char **device_names; 01948 char **hal_device_names; 01949 01950 message = dbus_message_new_method_call ("org.freedesktop.Hal", 01951 "/org/freedesktop/Hal/Manager", 01952 "org.freedesktop.Hal.Manager", 01953 "FindDeviceByCapability"); 01954 if (message == NULL) { 01955 fprintf (stderr, 01956 "%s %d : Couldn't allocate D-BUS message\n", 01957 __FILE__, __LINE__); 01958 return NULL; 01959 } 01960 01961 dbus_message_iter_init (message, &iter); 01962 dbus_message_iter_append_string (&iter, capability); 01963 01964 dbus_error_init (&error); 01965 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 01966 message, -1, 01967 &error); 01968 if (dbus_error_is_set (&error)) { 01969 fprintf (stderr, "%s %d : Error sending msg: %s\n", 01970 __FILE__, __LINE__, error.message); 01971 dbus_message_unref (message); 01972 return NULL; 01973 } 01974 if (reply == NULL) { 01975 dbus_message_unref (message); 01976 return NULL; 01977 } 01978 /* now analyse reply */ 01979 dbus_message_iter_init (reply, &iter); 01980 if (!dbus_message_iter_get_string_array (&iter, 01981 &device_names, 01982 num_devices)) { 01983 fprintf (stderr, "%s %d : wrong reply from hald\n", 01984 __FILE__, __LINE__); 01985 return NULL; 01986 } 01987 01988 dbus_message_unref (message); 01989 dbus_message_unref (reply); 01990 01991 /* Have to convert from dbus string array to hal string array 01992 * since we can't poke at the dbus string array for the reason 01993 * that d-bus use their own memory allocation scheme 01994 */ 01995 hal_device_names = malloc (sizeof (char *) * ((*num_devices) + 1)); 01996 if (hal_device_names == NULL) 01997 return NULL; 02000 for (i = 0; i < (*num_devices); i++) { 02001 hal_device_names[i] = strdup (device_names[i]); 02002 if (hal_device_names[i] == NULL) 02003 return NULL; 02005 } 02006 hal_device_names[i] = NULL; 02007 02008 dbus_free_string_array (device_names); 02009 02010 return hal_device_names; 02011 } 02012 02020 int 02021 hal_device_property_watch_all (LibHalContext *ctx) 02022 { 02023 DBusError error; 02024 02025 dbus_error_init (&error); 02026 02027 dbus_bus_add_match (ctx->connection, 02028 "type='signal'," 02029 "interface='org.freedesktop.Hal.Device'," 02030 "sender='org.freedesktop.Hal'", &error); 02031 if (dbus_error_is_set (&error)) { 02032 fprintf (stderr, "%s %d : Error subscribing to signals, " 02033 "error=%s\r\n", 02034 __FILE__, __LINE__, error.message); 02035 return 1; 02036 } 02037 return 0; 02038 } 02039 02040 02052 int 02053 hal_device_add_property_watch (LibHalContext *ctx, const char *udi) 02054 { 02055 char buf[512]; 02056 DBusError error; 02057 02058 dbus_error_init (&error); 02059 02060 snprintf (buf, 512, 02061 "type='signal'," 02062 "interface='org.freedesktop.Hal.Device'," 02063 "sender='org.freedesktop.Hal'," "path=%s", udi); 02064 02065 dbus_bus_add_match (ctx->connection, buf, &error); 02066 if (dbus_error_is_set (&error)) { 02067 fprintf (stderr, "%s %d : Error subscribing to signals, " 02068 "error=%s\r\n", 02069 __FILE__, __LINE__, error.message); 02070 return 1; 02071 } 02072 return 0; 02073 } 02074 02075 02083 int 02084 hal_device_remove_property_watch (LibHalContext *ctx, const char *udi) 02085 { 02086 char buf[512]; 02087 DBusError error; 02088 02089 dbus_error_init (&error); 02090 02091 snprintf (buf, 512, 02092 "type='signal'," 02093 "interface='org.freedesktop.Hal.Device'," 02094 "sender='org.freedesktop.Hal'," "path=%s", udi); 02095 02096 dbus_bus_remove_match (ctx->connection, buf, &error); 02097 if (dbus_error_is_set (&error)) { 02098 fprintf (stderr, "%s %d : Error unsubscribing to signals, " 02099 "error=%s\r\n", 02100 __FILE__, __LINE__, error.message); 02101 return 1; 02102 } 02103 return 0; 02104 } 02105 02106

Generated on Tue Aug 17 01:25:53 2004 for HAL by doxygen 1.3.8