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

libhal.c

00001 /*************************************************************************** 00002 * CVSID: $Id: libhal.c,v 1.26 2004/09/17 17:05:48 joe 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 dbus_uint64_t uint64_value; 00094 double double_value; 00095 dbus_bool_t bool_value; 00097 }; 00098 00099 LibHalProperty *next; 00101 }; 00102 00104 struct LibHalContext_s { 00105 DBusConnection *connection; 00106 dbus_bool_t is_initialized; 00107 dbus_bool_t cache_enabled; 00108 const LibHalFunctions *functions; 00109 void *user_data; 00110 }; 00111 00117 void 00118 hal_ctx_set_user_data(LibHalContext *ctx, void *user_data) 00119 { 00120 ctx->user_data = user_data; 00121 } 00122 00129 void* 00130 hal_ctx_get_user_data(LibHalContext *ctx) 00131 { 00132 return ctx->user_data; 00133 } 00134 00135 00143 LibHalPropertySet * 00144 hal_device_get_all_properties (LibHalContext *ctx, const char *udi) 00145 { 00146 DBusError error; 00147 DBusMessage *message; 00148 DBusMessage *reply; 00149 DBusMessageIter iter; 00150 DBusMessageIter dict_iter; 00151 LibHalPropertySet *result; 00152 LibHalProperty **pn; 00153 00154 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, 00155 "org.freedesktop.Hal.Device", 00156 "GetAllProperties"); 00157 if (message == NULL) { 00158 fprintf (stderr, 00159 "%s %d : Couldn't allocate D-BUS message\n", 00160 __FILE__, __LINE__); 00161 return NULL; 00162 } 00163 00164 dbus_error_init (&error); 00165 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 00166 message, -1, 00167 &error); 00168 if (dbus_error_is_set (&error)) { 00169 fprintf (stderr, "%s %d: %s raised\n\"%s\"\n\n", __FILE__, 00170 __LINE__, error.name, error.message); 00171 dbus_message_unref (message); 00172 return NULL; 00173 } 00174 00175 if (reply == NULL) { 00176 dbus_message_unref (message); 00177 return NULL; 00178 } 00179 00180 dbus_message_iter_init (reply, &iter); 00181 00182 result = malloc (sizeof (LibHalPropertySet)); 00183 if (result == NULL) { 00184 fprintf (stderr, "%s %d : error allocating memory\n", 00185 __FILE__, __LINE__); 00186 dbus_message_unref (message); 00187 dbus_message_unref (reply); 00188 return NULL; 00189 } 00190 00191 /* 00192 result->properties = malloc(sizeof(LibHalProperty)*result->num_properties); 00193 if( result->properties==NULL ) 00194 { 00196 return NULL; 00197 } 00198 */ 00199 00200 pn = &result->properties_head; 00201 result->num_properties = 0; 00202 00203 dbus_message_iter_init_dict_iterator (&iter, &dict_iter); 00204 00205 do { 00206 char *dbus_str; 00207 LibHalProperty *p; 00208 00209 p = malloc (sizeof (LibHalProperty)); 00210 if (p == NULL) { 00211 fprintf (stderr, 00212 "%s %d : error allocating memory\n", 00213 __FILE__, __LINE__); 00215 return NULL; 00216 } 00217 00218 *pn = p; 00219 pn = &p->next; 00220 p->next = NULL; 00221 result->num_properties++; 00222 00223 dbus_str = dbus_message_iter_get_dict_key (&dict_iter); 00224 p->key = 00225 (char *) ((dbus_str != NULL) ? strdup (dbus_str) : 00226 NULL); 00227 if (p->key == NULL) { 00228 fprintf (stderr, 00229 "%s %d : error allocating memory\n", 00230 __FILE__, __LINE__); 00232 return NULL; 00233 } 00234 dbus_free (dbus_str); 00235 00236 p->type = dbus_message_iter_get_arg_type (&dict_iter); 00237 00238 switch (p->type) { 00239 case DBUS_TYPE_STRING: 00240 dbus_str = 00241 dbus_message_iter_get_string (&dict_iter); 00242 p->str_value = 00243 (char *) ((dbus_str != NULL) ? 00244 strdup (dbus_str) : NULL); 00245 if (p->str_value == NULL) { 00246 fprintf (stderr, 00247 "%s %d : error allocating memory\n", 00248 __FILE__, __LINE__); 00250 return NULL; 00251 } 00252 dbus_free (dbus_str); 00253 break; 00254 case DBUS_TYPE_INT32: 00255 p->int_value = 00256 dbus_message_iter_get_int32 (&dict_iter); 00257 break; 00258 case DBUS_TYPE_UINT64: 00259 p->uint64_value = 00260 dbus_message_iter_get_uint64 (&dict_iter); 00261 break; 00262 case DBUS_TYPE_DOUBLE: 00263 p->double_value = 00264 dbus_message_iter_get_double (&dict_iter); 00265 break; 00266 case DBUS_TYPE_BOOLEAN: 00267 p->bool_value = 00268 dbus_message_iter_get_boolean (&dict_iter); 00269 break; 00270 00271 default: 00273 break; 00274 } 00275 00276 } 00277 while (dbus_message_iter_has_next (&dict_iter) && 00278 dbus_message_iter_next (&dict_iter)); 00279 00280 dbus_message_unref (message); 00281 dbus_message_unref (reply); 00282 00283 return result; 00284 } 00285 00290 void 00291 hal_free_property_set (LibHalPropertySet * set) 00292 { 00293 LibHalProperty *p; 00294 LibHalProperty *q; 00295 00296 for (p = set->properties_head; p != NULL; p = q) { 00297 free (p->key); 00298 if (p->type == DBUS_TYPE_STRING) 00299 free (p->str_value); 00300 q = p->next; 00301 free (p); 00302 } 00303 free (set); 00304 } 00305 00311 void 00312 hal_psi_init (LibHalPropertySetIterator * iter, LibHalPropertySet * set) 00313 { 00314 iter->set = set; 00315 iter->index = 0; 00316 iter->cur_prop = set->properties_head; 00317 } 00318 00324 dbus_bool_t 00325 hal_psi_has_more (LibHalPropertySetIterator * iter) 00326 { 00327 return iter->index < iter->set->num_properties; 00328 } 00329 00334 void 00335 hal_psi_next (LibHalPropertySetIterator * iter) 00336 { 00337 iter->index++; 00338 iter->cur_prop = iter->cur_prop->next; 00339 } 00340 00347 int 00348 hal_psi_get_type (LibHalPropertySetIterator * iter) 00349 { 00350 return iter->cur_prop->type; 00351 } 00352 00361 char * 00362 hal_psi_get_key (LibHalPropertySetIterator * iter) 00363 { 00364 return iter->cur_prop->key; 00365 } 00366 00375 char * 00376 hal_psi_get_string (LibHalPropertySetIterator * iter) 00377 { 00378 return iter->cur_prop->str_value; 00379 } 00380 00386 dbus_int32_t 00387 hal_psi_get_int (LibHalPropertySetIterator * iter) 00388 { 00389 return iter->cur_prop->int_value; 00390 } 00391 00397 dbus_uint64_t 00398 hal_psi_get_uint64 (LibHalPropertySetIterator * iter) 00399 { 00400 return iter->cur_prop->uint64_value; 00401 } 00402 00408 double 00409 hal_psi_get_double (LibHalPropertySetIterator * iter) 00410 { 00411 return iter->cur_prop->double_value; 00412 } 00413 00419 dbus_bool_t 00420 hal_psi_get_bool (LibHalPropertySetIterator * iter) 00421 { 00422 return iter->cur_prop->bool_value; 00423 } 00424 00425 00426 #ifndef DOXYGEN_SHOULD_SKIP_THIS 00427 static DBusHandlerResult 00428 filter_func (DBusConnection * connection, 00429 DBusMessage * message, void *user_data) 00430 { 00431 const char *object_path; 00432 DBusError error; 00433 LibHalContext *ctx = (LibHalContext *) user_data; 00434 00435 dbus_error_init (&error); 00436 00437 object_path = dbus_message_get_path (message); 00438 00439 /*printf("*** in filter_func, object_path=%s\n", object_path); */ 00440 00441 if (dbus_message_is_signal (message, "org.freedesktop.Hal.Manager", 00442 "DeviceAdded")) { 00443 char *udi; 00444 if (dbus_message_get_args (message, &error, 00445 DBUS_TYPE_STRING, &udi, 00446 DBUS_TYPE_INVALID)) { 00447 if (ctx->functions->device_added != NULL) { 00448 ctx->functions->device_added (ctx, udi); 00449 } 00450 dbus_free (udi); 00451 } 00452 return DBUS_HANDLER_RESULT_HANDLED; 00453 } else 00454 if (dbus_message_is_signal 00455 (message, "org.freedesktop.Hal.Manager", 00456 "DeviceRemoved")) { 00457 char *udi; 00458 if (dbus_message_get_args (message, &error, 00459 DBUS_TYPE_STRING, &udi, 00460 DBUS_TYPE_INVALID)) { 00461 if (ctx->functions->device_removed != NULL) { 00462 ctx->functions->device_removed (ctx, udi); 00463 } 00464 dbus_free (udi); 00465 } 00466 return DBUS_HANDLER_RESULT_HANDLED; 00467 } else 00468 if (dbus_message_is_signal 00469 (message, "org.freedesktop.Hal.Manager", 00470 "NewCapability")) { 00471 char *udi; 00472 char *capability; 00473 if (dbus_message_get_args (message, &error, 00474 DBUS_TYPE_STRING, &udi, 00475 DBUS_TYPE_STRING, &capability, 00476 DBUS_TYPE_INVALID)) { 00477 if (ctx->functions->device_new_capability != NULL) { 00478 ctx->functions->device_new_capability (ctx, 00479 udi, 00480 capability); 00481 } 00482 dbus_free (udi); 00483 dbus_free (capability); 00484 } 00485 return DBUS_HANDLER_RESULT_HANDLED; 00486 } else 00487 if (dbus_message_is_signal 00488 (message, "org.freedesktop.Hal.Device", "Condition")) { 00489 if (ctx->functions->device_condition != NULL) { 00490 DBusMessageIter iter; 00491 char *condition_name; 00492 00493 dbus_message_iter_init (message, &iter); 00494 condition_name = 00495 dbus_message_iter_get_string (&iter); 00496 00497 ctx->functions->device_condition (ctx, 00498 object_path, 00499 condition_name, 00500 message); 00501 00502 dbus_free (condition_name); 00503 } 00504 return DBUS_HANDLER_RESULT_HANDLED; 00505 } else 00506 if (dbus_message_is_signal 00507 (message, "org.freedesktop.Hal.Device", 00508 "PropertyModified")) { 00509 if (ctx->functions->device_property_modified != NULL) { 00510 int i; 00511 char *key; 00512 dbus_bool_t removed, added; 00513 int num_modifications; 00514 DBusMessageIter iter; 00515 00516 dbus_message_iter_init (message, &iter); 00517 num_modifications = 00518 dbus_message_iter_get_int32 (&iter); 00519 dbus_message_iter_next (&iter); 00520 00521 00522 for (i = 0; i < num_modifications; i++) { 00523 00524 key = dbus_message_iter_get_string (&iter); 00525 dbus_message_iter_next (&iter); 00526 removed = 00527 dbus_message_iter_get_boolean (&iter); 00528 dbus_message_iter_next (&iter); 00529 added = 00530 dbus_message_iter_get_boolean (&iter); 00531 dbus_message_iter_next (&iter); 00532 00533 ctx->functions-> 00534 device_property_modified (ctx, 00535 object_path, 00536 key, removed, 00537 added); 00538 00539 dbus_free (key); 00540 } 00541 00542 } 00543 return DBUS_HANDLER_RESULT_HANDLED; 00544 } 00545 00546 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 00547 } 00548 00549 static LibHalFunctions hal_null_functions = { 00550 NULL /*mainloop_integration */ , 00551 NULL /*device_added */ , 00552 NULL /*device_removed */ , 00553 NULL /*device_new_capability */ , 00554 NULL /*device_lost_capability */ , 00555 NULL /*property_modified */ , 00556 NULL /*device_condition */ 00557 }; 00558 #endif /* DOXYGEN_SHOULD_SKIP_THIS */ 00559 00578 LibHalContext* 00579 hal_initialize (const LibHalFunctions * cb_functions, 00580 dbus_bool_t use_cache) 00581 { 00582 DBusError error; 00583 LibHalContext *ctx; 00584 00585 ctx = malloc (sizeof (LibHalContext)); 00586 if (ctx == NULL) { 00587 fprintf (stderr, "%s %d : Cannot allocated %d bytes!\n", 00588 __FILE__, __LINE__, sizeof (LibHalContext)); 00589 return NULL; 00590 } 00591 00592 ctx->cache_enabled = use_cache; 00593 00594 ctx->functions = cb_functions; 00595 /* allow caller to pass NULL */ 00596 if (ctx->functions == NULL) 00597 ctx->functions = &hal_null_functions; 00598 00599 /* connect to hald service on the system bus */ 00600 dbus_error_init (&error); 00601 ctx->connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error); 00602 if (ctx->connection == NULL) { 00603 fprintf (stderr, 00604 "%s %d : Error connecting to system bus: %s\n", 00605 __FILE__, __LINE__, error.message); 00606 dbus_error_free (&error); 00607 return NULL; 00608 } 00609 00610 if (ctx->functions->main_loop_integration != NULL) { 00611 00612 ctx->functions->main_loop_integration (ctx, ctx->connection); 00613 } 00614 00615 if (!dbus_connection_add_filter 00616 (ctx->connection, filter_func, ctx, NULL)) { 00617 fprintf (stderr, 00618 "%s %d : Error creating connection handler\r\n", 00619 __FILE__, __LINE__); 00621 return NULL; 00622 } 00623 00624 dbus_bus_add_match (ctx->connection, 00625 "type='signal'," 00626 "interface='org.freedesktop.Hal.Manager'," 00627 "sender='org.freedesktop.Hal'," 00628 "path='/org/freedesktop/Hal/Manager'", &error); 00629 if (dbus_error_is_set (&error)) { 00630 fprintf (stderr, "%s %d : Error subscribing to signals, " 00631 "error=%s\r\n", 00632 __FILE__, __LINE__, error.message); 00634 return NULL; 00635 } 00636 00637 ctx->is_initialized = TRUE; 00638 00639 return ctx; 00640 } 00641 00648 int 00649 hal_shutdown (LibHalContext *ctx) 00650 { 00651 if (!ctx->is_initialized) 00652 return 1; 00653 00655 free (ctx); 00656 return 0; 00657 } 00658 00668 char ** 00669 hal_get_all_devices (LibHalContext *ctx, int *num_devices) 00670 { 00671 int i; 00672 DBusError error; 00673 DBusMessage *message; 00674 DBusMessage *reply; 00675 DBusMessageIter iter; 00676 char **device_names; 00677 char **hal_device_names; 00678 00679 message = dbus_message_new_method_call ("org.freedesktop.Hal", 00680 "/org/freedesktop/Hal/Manager", 00681 "org.freedesktop.Hal.Manager", 00682 "GetAllDevices"); 00683 if (message == NULL) { 00684 fprintf (stderr, 00685 "%s %d : Couldn't allocate D-BUS message\n", 00686 __FILE__, __LINE__); 00687 return NULL; 00688 } 00689 00690 dbus_error_init (&error); 00691 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 00692 message, -1, 00693 &error); 00694 if (dbus_error_is_set (&error)) { 00695 fprintf (stderr, "%s %d : %s raised\n\"%s\"\n\n", __FILE__, 00696 __LINE__, error.name, error.message); 00697 dbus_message_unref (message); 00698 return NULL; 00699 } 00700 00701 if (reply == NULL) { 00702 dbus_message_unref (message); 00703 return NULL; 00704 } 00705 00706 /* now analyze reply */ 00707 dbus_message_iter_init (reply, &iter); 00708 if (!dbus_message_iter_get_string_array (&iter, 00709 &device_names, 00710 num_devices)) { 00711 fprintf (stderr, "%s %d : wrong reply from hald\n", 00712 __FILE__, __LINE__); 00713 return NULL; 00714 } 00715 00716 dbus_message_unref (reply); 00717 dbus_message_unref (message); 00718 00719 /* Have to convert from dbus string array to hal string array 00720 * since we can't poke at the dbus string array for the reason 00721 * that d-bus use their own memory allocation scheme 00722 */ 00723 hal_device_names = malloc (sizeof (char *) * ((*num_devices) + 1)); 00724 if (hal_device_names == NULL) 00725 return NULL; 00728 for (i = 0; i < (*num_devices); i++) { 00729 hal_device_names[i] = strdup (device_names[i]); 00730 if (hal_device_names[i] == NULL) { 00731 fprintf (stderr, 00732 "%s %d : error allocating memory\n", 00733 __FILE__, __LINE__); 00735 return NULL; 00736 } 00737 } 00738 hal_device_names[i] = NULL; 00739 00740 dbus_free_string_array (device_names); 00741 00742 return hal_device_names; 00743 } 00744 00754 int 00755 hal_device_get_property_type (LibHalContext *ctx, 00756 const char *udi, const char *key) 00757 { 00758 DBusError error; 00759 DBusMessage *message; 00760 DBusMessage *reply; 00761 DBusMessageIter iter; 00762 int type; 00763 00764 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, 00765 "org.freedesktop.Hal.Device", 00766 "GetPropertyType"); 00767 if (message == NULL) { 00768 fprintf (stderr, 00769 "%s %d : Couldn't allocate D-BUS message\n", 00770 __FILE__, __LINE__); 00771 return DBUS_TYPE_NIL; 00772 } 00773 00774 dbus_message_iter_init (message, &iter); 00775 dbus_message_iter_append_string (&iter, key); 00776 dbus_error_init (&error); 00777 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 00778 message, -1, 00779 &error); 00780 if (dbus_error_is_set (&error)) { 00781 fprintf (stderr, "%s %d : %s raised\n\"%s\"\n\n", __FILE__, 00782 __LINE__, error.name, error.message); 00783 dbus_message_unref (message); 00784 return DBUS_TYPE_NIL; 00785 } 00786 if (reply == NULL) { 00787 dbus_message_unref (message); 00788 return DBUS_TYPE_NIL; 00789 } 00790 00791 dbus_message_iter_init (reply, &iter); 00792 type = dbus_message_iter_get_int32 (&iter); 00793 00794 dbus_message_unref (message); 00795 dbus_message_unref (reply); 00796 00797 return type; 00798 } 00799 00811 char * 00812 hal_device_get_property_string (LibHalContext *ctx, 00813 const char *udi, const char *key) 00814 { 00815 DBusError error; 00816 DBusMessage *message; 00817 DBusMessage *reply; 00818 DBusMessageIter iter; 00819 char *value; 00820 char *dbus_str; 00821 00822 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, 00823 "org.freedesktop.Hal.Device", 00824 "GetPropertyString"); 00825 if (message == NULL) { 00826 fprintf (stderr, 00827 "%s %d : Couldn't allocate D-BUS message\n", 00828 __FILE__, __LINE__); 00829 return NULL; 00830 } 00831 00832 dbus_message_iter_init (message, &iter); 00833 dbus_message_iter_append_string (&iter, key); 00834 dbus_error_init (&error); 00835 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 00836 message, -1, 00837 &error); 00838 if (dbus_error_is_set (&error)) { 00839 fprintf (stderr, "%s %d : Error sending msg: %s\n", 00840 __FILE__, __LINE__, error.message); 00841 dbus_message_unref (message); 00842 return NULL; 00843 } 00844 if (reply == NULL) { 00845 dbus_message_unref (message); 00846 return NULL; 00847 } 00848 00849 dbus_message_iter_init (reply, &iter); 00850 00851 /* now analyze reply */ 00852 if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_NIL) { 00853 fprintf (stderr, 00854 "%s %d : property '%s' for device '%s' does not " 00855 "exist\n", __FILE__, __LINE__, key, udi); 00856 dbus_message_unref (message); 00857 dbus_message_unref (reply); 00858 return NULL; 00859 } else if (dbus_message_iter_get_arg_type (&iter) != 00860 DBUS_TYPE_STRING) { 00861 fprintf (stderr, 00862 "%s %d : property '%s' for device '%s' is not " 00863 "of type string\n", __FILE__, __LINE__, key, udi); 00864 dbus_message_unref (message); 00865 dbus_message_unref (reply); 00866 return NULL; 00867 } 00868 00869 dbus_str = dbus_message_iter_get_string (&iter); 00870 value = (char *) ((dbus_str != NULL) ? strdup (dbus_str) : NULL); 00871 if (value == NULL) { 00872 fprintf (stderr, "%s %d : error allocating memory\n", 00873 __FILE__, __LINE__); 00875 return NULL; 00876 } 00877 dbus_free (dbus_str); 00878 00879 dbus_message_unref (message); 00880 dbus_message_unref (reply); 00881 return value; 00882 } 00883 00891 dbus_int32_t 00892 hal_device_get_property_int (LibHalContext *ctx, 00893 const char *udi, const char *key) 00894 { 00895 DBusError error; 00896 DBusMessage *message; 00897 DBusMessage *reply; 00898 DBusMessageIter iter; 00899 dbus_int32_t value; 00900 00901 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, 00902 "org.freedesktop.Hal.Device", 00903 "GetPropertyInteger"); 00904 if (message == NULL) { 00905 fprintf (stderr, 00906 "%s %d : Couldn't allocate D-BUS message\n", 00907 __FILE__, __LINE__); 00908 return -1; 00909 } 00910 00911 dbus_message_iter_init (message, &iter); 00912 dbus_message_iter_append_string (&iter, key); 00913 dbus_error_init (&error); 00914 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 00915 message, -1, 00916 &error); 00917 if (dbus_error_is_set (&error)) { 00918 fprintf (stderr, "%s %d : Error sending msg: %s\n", 00919 __FILE__, __LINE__, error.message); 00920 dbus_message_unref (message); 00921 return -1; 00922 } 00923 if (reply == NULL) { 00924 dbus_message_unref (message); 00925 return -1; 00926 } 00927 00928 dbus_message_iter_init (reply, &iter); 00929 00930 /* now analyze reply */ 00931 if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_NIL) { 00932 /* property didn't exist */ 00933 fprintf (stderr, 00934 "%s %d : property '%s' for device '%s' does not " 00935 "exist\n", __FILE__, __LINE__, key, udi); 00936 dbus_message_unref (message); 00937 dbus_message_unref (reply); 00938 return -1; 00939 } else if (dbus_message_iter_get_arg_type (&iter) != 00940 DBUS_TYPE_INT32) { 00941 fprintf (stderr, 00942 "%s %d : property '%s' for device '%s' is not " 00943 "of type integer\n", __FILE__, __LINE__, key, 00944 udi); 00945 dbus_message_unref (message); 00946 dbus_message_unref (reply); 00947 return -1; 00948 } 00949 value = dbus_message_iter_get_int32 (&iter); 00950 00951 dbus_message_unref (message); 00952 dbus_message_unref (reply); 00953 return value; 00954 } 00955 00963 dbus_uint64_t 00964 hal_device_get_property_uint64 (LibHalContext *ctx, 00965 const char *udi, const char *key) 00966 { 00967 DBusError error; 00968 DBusMessage *message; 00969 DBusMessage *reply; 00970 DBusMessageIter iter; 00971 dbus_uint64_t value; 00972 00973 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, 00974 "org.freedesktop.Hal.Device", 00975 "GetPropertyInteger"); 00976 if (message == NULL) { 00977 fprintf (stderr, 00978 "%s %d : Couldn't allocate D-BUS message\n", 00979 __FILE__, __LINE__); 00980 return -1; 00981 } 00982 00983 dbus_message_iter_init (message, &iter); 00984 dbus_message_iter_append_string (&iter, key); 00985 dbus_error_init (&error); 00986 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 00987 message, -1, 00988 &error); 00989 if (dbus_error_is_set (&error)) { 00990 fprintf (stderr, "%s %d : Error sending msg: %s\n", 00991 __FILE__, __LINE__, error.message); 00992 dbus_message_unref (message); 00993 return -1; 00994 } 00995 if (reply == NULL) { 00996 dbus_message_unref (message); 00997 return -1; 00998 } 00999 01000 dbus_message_iter_init (reply, &iter); 01001 01002 /* now analyze reply */ 01003 if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_NIL) { 01004 /* property didn't exist */ 01005 fprintf (stderr, 01006 "%s %d : property '%s' for device '%s' does not " 01007 "exist\n", __FILE__, __LINE__, key, udi); 01008 dbus_message_unref (message); 01009 dbus_message_unref (reply); 01010 return -1; 01011 } else if (dbus_message_iter_get_arg_type (&iter) != 01012 DBUS_TYPE_UINT64) { 01013 fprintf (stderr, 01014 "%s %d : property '%s' for device '%s' is not " 01015 "of type integer\n", __FILE__, __LINE__, key, 01016 udi); 01017 dbus_message_unref (message); 01018 dbus_message_unref (reply); 01019 return -1; 01020 } 01021 value = dbus_message_iter_get_uint64 (&iter); 01022 01023 dbus_message_unref (message); 01024 dbus_message_unref (reply); 01025 return value; 01026 } 01027 01035 double 01036 hal_device_get_property_double (LibHalContext *ctx, 01037 const char *udi, const char *key) 01038 { 01039 DBusError error; 01040 DBusMessage *message; 01041 DBusMessage *reply; 01042 DBusMessageIter iter; 01043 double value; 01044 01045 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, 01046 "org.freedesktop.Hal.Device", 01047 "GetPropertyDouble"); 01048 if (message == NULL) { 01049 fprintf (stderr, 01050 "%s %d : Couldn't allocate D-BUS message\n", 01051 __FILE__, __LINE__); 01052 return -1.0f; 01053 } 01054 01055 dbus_message_iter_init (message, &iter); 01056 dbus_message_iter_append_string (&iter, key); 01057 dbus_error_init (&error); 01058 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 01059 message, -1, 01060 &error); 01061 if (dbus_error_is_set (&error)) { 01062 fprintf (stderr, "%s %d : Error sending msg: %s\n", 01063 __FILE__, __LINE__, error.message); 01064 dbus_message_unref (message); 01065 return -1.0f; 01066 } 01067 if (reply == NULL) { 01068 dbus_message_unref (message); 01069 return -1.0f; 01070 } 01071 01072 dbus_message_iter_init (reply, &iter); 01073 01074 /* now analyze reply */ 01075 if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_NIL) { 01076 /* property didn't exist */ 01077 fprintf (stderr, 01078 "%s %d : property '%s' for device '%s' does not " 01079 "exist\n", __FILE__, __LINE__, key, udi); 01080 dbus_message_unref (message); 01081 dbus_message_unref (reply); 01082 return -1.0f; 01083 } else if (dbus_message_iter_get_arg_type (&iter) != 01084 DBUS_TYPE_DOUBLE) { 01085 fprintf (stderr, 01086 "%s %d : property '%s' for device '%s' is not " 01087 "of type double\n", __FILE__, __LINE__, key, udi); 01088 dbus_message_unref (message); 01089 dbus_message_unref (reply); 01090 return -1.0f; 01091 } 01092 value = dbus_message_iter_get_double (&iter); 01093 01094 dbus_message_unref (message); 01095 dbus_message_unref (reply); 01096 return (double) value; 01097 } 01098 01106 dbus_bool_t 01107 hal_device_get_property_bool (LibHalContext *ctx, 01108 const char *udi, const char *key) 01109 { 01110 DBusError error; 01111 DBusMessage *message; 01112 DBusMessage *reply; 01113 DBusMessageIter iter; 01114 double value; 01115 01116 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, 01117 "org.freedesktop.Hal.Device", 01118 "GetPropertyBoolean"); 01119 if (message == NULL) { 01120 fprintf (stderr, 01121 "%s %d : Couldn't allocate D-BUS message\n", 01122 __FILE__, __LINE__); 01123 return FALSE; 01124 } 01125 01126 dbus_message_iter_init (message, &iter); 01127 dbus_message_iter_append_string (&iter, key); 01128 dbus_error_init (&error); 01129 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 01130 message, -1, 01131 &error); 01132 if (dbus_error_is_set (&error)) { 01133 fprintf (stderr, "%s %d : Error sending msg: %s\n", 01134 __FILE__, __LINE__, error.message); 01135 dbus_message_unref (message); 01136 return FALSE; 01137 } 01138 if (reply == NULL) { 01139 dbus_message_unref (message); 01140 return FALSE; 01141 } 01142 01143 dbus_message_iter_init (reply, &iter); 01144 01145 /* now analyze reply */ 01146 if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_NIL) { 01147 /* property didn't exist */ 01148 fprintf (stderr, 01149 "%s %d : property '%s' for device '%s' does not " 01150 "exist\n", __FILE__, __LINE__, key, udi); 01151 dbus_message_unref (message); 01152 dbus_message_unref (reply); 01153 return FALSE; 01154 } else if (dbus_message_iter_get_arg_type (&iter) != 01155 DBUS_TYPE_BOOLEAN) { 01156 fprintf (stderr, 01157 "%s %d : property '%s' for device '%s' is not " 01158 "of type bool\n", __FILE__, __LINE__, key, udi); 01159 dbus_message_unref (message); 01160 dbus_message_unref (reply); 01161 return FALSE; 01162 } 01163 value = dbus_message_iter_get_boolean (&iter); 01164 01165 dbus_message_unref (message); 01166 dbus_message_unref (reply); 01167 return value; 01168 } 01169 01170 01171 /* generic helper */ 01172 static int 01173 hal_device_set_property_helper (LibHalContext *ctx, 01174 const char *udi, 01175 const char *key, 01176 int type, 01177 const char *str_value, 01178 dbus_int32_t int_value, 01179 dbus_uint64_t uint64_value, 01180 double double_value, 01181 dbus_bool_t bool_value) 01182 { 01183 DBusError error; 01184 DBusMessage *message; 01185 DBusMessage *reply; 01186 DBusMessageIter iter; 01187 char *method_name = NULL; 01188 01191 switch (type) { 01192 case DBUS_TYPE_NIL: 01193 method_name = "RemoveProperty"; 01194 break; 01195 case DBUS_TYPE_STRING: 01196 method_name = "SetPropertyString"; 01197 break; 01198 case DBUS_TYPE_INT32: 01199 case DBUS_TYPE_UINT64: 01200 method_name = "SetPropertyInteger"; 01201 break; 01202 case DBUS_TYPE_DOUBLE: 01203 method_name = "SetPropertyDouble"; 01204 break; 01205 case DBUS_TYPE_BOOLEAN: 01206 method_name = "SetPropertyBoolean"; 01207 break; 01208 01209 default: 01210 /* cannot happen; is not callable from outside this file */ 01211 break; 01212 } 01213 01214 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, 01215 "org.freedesktop.Hal.Device", 01216 method_name); 01217 if (message == NULL) { 01218 fprintf (stderr, 01219 "%s %d : Couldn't allocate D-BUS message\n", 01220 __FILE__, __LINE__); 01221 return FALSE; 01222 } 01223 01224 dbus_message_iter_init (message, &iter); 01225 dbus_message_iter_append_string (&iter, key); 01226 switch (type) { 01227 case DBUS_TYPE_NIL: 01228 dbus_message_iter_append_nil (&iter); 01229 break; 01230 case DBUS_TYPE_STRING: 01231 dbus_message_iter_append_string (&iter, str_value); 01232 break; 01233 case DBUS_TYPE_INT32: 01234 dbus_message_iter_append_int32 (&iter, int_value); 01235 break; 01236 case DBUS_TYPE_UINT64: 01237 dbus_message_iter_append_uint64 (&iter, uint64_value); 01238 break; 01239 case DBUS_TYPE_DOUBLE: 01240 dbus_message_iter_append_double (&iter, double_value); 01241 break; 01242 case DBUS_TYPE_BOOLEAN: 01243 dbus_message_iter_append_boolean (&iter, bool_value); 01244 break; 01245 } 01246 01247 dbus_error_init (&error); 01248 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 01249 message, -1, 01250 &error); 01251 if (dbus_error_is_set (&error)) { 01252 fprintf (stderr, "%s %d: %s raised\n\"%s\"\n\n", __FILE__, 01253 __LINE__, error.name, error.message); 01254 dbus_message_unref (message); 01255 return FALSE; 01256 } 01257 01258 if (reply == NULL) { 01259 dbus_message_unref (message); 01260 return FALSE; 01261 } 01262 01263 return TRUE; 01264 } 01265 01276 dbus_bool_t 01277 hal_device_set_property_string (LibHalContext *ctx, 01278 const char *udi, 01279 const char *key, const char *value) 01280 { 01281 return hal_device_set_property_helper (ctx, udi, key, 01282 DBUS_TYPE_STRING, 01283 value, 0, 0, 0.0f, FALSE); 01284 } 01285 01296 dbus_bool_t 01297 hal_device_set_property_int (LibHalContext *ctx, const char *udi, 01298 const char *key, dbus_int32_t value) 01299 { 01300 return hal_device_set_property_helper (ctx, udi, key, 01301 DBUS_TYPE_INT32, 01302 NULL, value, 0, 0.0f, FALSE); 01303 } 01304 01315 dbus_bool_t 01316 hal_device_set_property_uint64 (LibHalContext *ctx, const char *udi, 01317 const char *key, dbus_uint64_t value) 01318 { 01319 return hal_device_set_property_helper (ctx, udi, key, 01320 DBUS_TYPE_UINT64, 01321 NULL, 0, value, 0.0f, FALSE); 01322 } 01323 01334 dbus_bool_t 01335 hal_device_set_property_double (LibHalContext *ctx, const char *udi, 01336 const char *key, double value) 01337 { 01338 return hal_device_set_property_helper (ctx, udi, key, 01339 DBUS_TYPE_DOUBLE, 01340 NULL, 0, 0, value, FALSE); 01341 } 01342 01353 dbus_bool_t 01354 hal_device_set_property_bool (LibHalContext *ctx, const char *udi, 01355 const char *key, dbus_bool_t value) 01356 { 01357 return hal_device_set_property_helper (ctx, udi, key, 01358 DBUS_TYPE_BOOLEAN, 01359 NULL, 0, 0, 0.0f, value); 01360 } 01361 01362 01371 dbus_bool_t 01372 hal_device_remove_property (LibHalContext *ctx, 01373 const char *udi, const char *key) 01374 { 01375 return hal_device_set_property_helper (ctx, udi, key, DBUS_TYPE_NIL, 01376 /* DBUS_TYPE_NIL means remove */ 01377 NULL, 0, 0, 0.0f, FALSE); 01378 } 01379 01393 dbus_bool_t 01394 hal_device_lock (LibHalContext *ctx, 01395 const char *udi, 01396 const char *reason_to_lock, 01397 char **reason_why_locked) 01398 { 01399 DBusMessage *message; 01400 DBusMessageIter iter; 01401 DBusError error; 01402 DBusMessage *reply; 01403 01404 if (reason_why_locked != NULL) 01405 *reason_why_locked = NULL; 01406 01407 message = dbus_message_new_method_call ("org.freedesktop.Hal", 01408 udi, 01409 "org.freedesktop.Hal.Device", 01410 "Lock"); 01411 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 (message, &iter); 01420 dbus_message_iter_append_string (&iter, reason_to_lock); 01421 01422 dbus_error_init (&error); 01423 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 01424 message, -1, 01425 &error); 01426 01427 if (dbus_error_is_set (&error)) { 01428 if (strcmp (error.name, 01429 "org.freedesktop.Hal.DeviceAlreadyLocked") == 0) { 01430 if (reason_why_locked != NULL) { 01431 *reason_why_locked = 01432 dbus_malloc0 (strlen (error.message) + 1); 01433 strcpy (*reason_why_locked, error.message); 01434 } 01435 } else { 01436 fprintf (stderr, "%s %d: %s raised\n\"%s\"\n\n", 01437 __FILE__, __LINE__, error.name, 01438 error.message); 01439 } 01440 01441 dbus_message_unref (message); 01442 return FALSE; 01443 } 01444 01445 dbus_message_unref (message); 01446 01447 if (reply == NULL) 01448 return FALSE; 01449 01450 dbus_message_unref (reply); 01451 01452 return TRUE; 01453 } 01454 01463 dbus_bool_t 01464 hal_device_unlock (LibHalContext *ctx, 01465 const char *udi) 01466 { 01467 DBusMessage *message; 01468 DBusError error; 01469 DBusMessage *reply; 01470 01471 message = dbus_message_new_method_call ("org.freedesktop.Hal", 01472 udi, 01473 "org.freedesktop.Hal.Device", 01474 "Unlock"); 01475 01476 if (message == NULL) { 01477 fprintf (stderr, 01478 "%s %d : Couldn't allocate D-BUS message\n", 01479 __FILE__, __LINE__); 01480 return FALSE; 01481 } 01482 01483 dbus_error_init (&error); 01484 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 01485 message, -1, 01486 &error); 01487 01488 if (dbus_error_is_set (&error)) { 01489 fprintf (stderr, "%s %d: %s raised\n\"%s\"\n\n", __FILE__, 01490 __LINE__, error.name, error.message); 01491 dbus_message_unref (message); 01492 return FALSE; 01493 } 01494 01495 dbus_message_unref (message); 01496 01497 if (reply == NULL) 01498 return FALSE; 01499 01500 dbus_message_unref (reply); 01501 01502 return TRUE; 01503 } 01504 01505 01517 char * 01518 hal_agent_new_device (LibHalContext *ctx) 01519 { 01520 DBusError error; 01521 DBusMessage *message; 01522 DBusMessage *reply; 01523 DBusMessageIter iter; 01524 char *value; 01525 char *dbus_str; 01526 01527 message = dbus_message_new_method_call ("org.freedesktop.Hal", 01528 "/org/freedesktop/Hal/Manager", 01529 "org.freedesktop.Hal.AgentManager", 01530 "NewDevice"); 01531 if (message == NULL) { 01532 fprintf (stderr, 01533 "%s %d : Couldn't allocate D-BUS message\n", 01534 __FILE__, __LINE__); 01535 return NULL; 01536 } 01537 01538 dbus_error_init (&error); 01539 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 01540 message, -1, 01541 &error); 01542 if (dbus_error_is_set (&error)) { 01543 fprintf (stderr, "%s %d : Error sending msg: %s\n", 01544 __FILE__, __LINE__, error.message); 01545 dbus_message_unref (message); 01546 return NULL; 01547 } 01548 if (reply == NULL) { 01549 dbus_message_unref (message); 01550 return NULL; 01551 } 01552 01553 dbus_message_iter_init (reply, &iter); 01554 01555 /* now analyze reply */ 01556 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING) { 01557 fprintf (stderr, 01558 "%s %d : expected a string in reply to NewDevice\n", 01559 __FILE__, __LINE__); 01560 dbus_message_unref (message); 01561 dbus_message_unref (reply); 01562 return NULL; 01563 } 01564 01565 dbus_str = dbus_message_iter_get_string (&iter); 01566 value = (char *) ((dbus_str != NULL) ? strdup (dbus_str) : NULL); 01567 if (value == NULL) { 01568 fprintf (stderr, "%s %d : error allocating memory\n", 01569 __FILE__, __LINE__); 01571 return NULL; 01572 } 01573 dbus_free (dbus_str); 01574 01575 dbus_message_unref (message); 01576 dbus_message_unref (reply); 01577 return value; 01578 } 01579 01580 01599 dbus_bool_t 01600 hal_agent_commit_to_gdl (LibHalContext *ctx, 01601 const char *temp_udi, const char *udi) 01602 { 01603 DBusError error; 01604 DBusMessage *message; 01605 DBusMessage *reply; 01606 DBusMessageIter iter; 01607 01608 message = dbus_message_new_method_call ("org.freedesktop.Hal", 01609 "/org/freedesktop/Hal/Manager", 01610 "org.freedesktop.Hal.AgentManager", 01611 "CommitToGdl"); 01612 if (message == NULL) { 01613 fprintf (stderr, 01614 "%s %d : Couldn't allocate D-BUS message\n", 01615 __FILE__, __LINE__); 01616 return FALSE; 01617 } 01618 01619 dbus_message_iter_init (message, &iter); 01620 dbus_message_iter_append_string (&iter, temp_udi); 01621 dbus_message_iter_append_string (&iter, udi); 01622 01623 dbus_error_init (&error); 01624 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 01625 message, -1, 01626 &error); 01627 if (dbus_error_is_set (&error)) { 01628 if (dbus_error_has_name 01629 (&error, "org.freedesktop.Hal.UdiInUse")) 01630 return FALSE; 01631 fprintf (stderr, "%s %d : Error sending msg: %s\n", 01632 __FILE__, __LINE__, error.message); 01633 dbus_message_unref (message); 01634 return FALSE; 01635 } 01636 if (reply == NULL) { 01637 dbus_message_unref (message); 01638 return FALSE; 01639 } 01640 01641 dbus_message_unref (message); 01642 dbus_message_unref (reply); 01643 return TRUE; 01644 } 01645 01657 dbus_bool_t 01658 hal_agent_remove_device (LibHalContext *ctx, const char *udi) 01659 { 01660 DBusError error; 01661 DBusMessage *message; 01662 DBusMessage *reply; 01663 DBusMessageIter iter; 01664 01665 message = dbus_message_new_method_call ("org.freedesktop.Hal", 01666 "/org/freedesktop/Hal/Manager", 01667 "org.freedesktop.Hal.AgentManager", 01668 "Remove"); 01669 if (message == NULL) { 01670 fprintf (stderr, 01671 "%s %d : Couldn't allocate D-BUS message\n", 01672 __FILE__, __LINE__); 01673 return FALSE; 01674 } 01675 01676 dbus_message_iter_init (message, &iter); 01677 dbus_message_iter_append_string (&iter, udi); 01678 01679 dbus_error_init (&error); 01680 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 01681 message, -1, 01682 &error); 01683 if (dbus_error_is_set (&error)) { 01684 fprintf (stderr, "%s %d : Error sending msg: %s\n", 01685 __FILE__, __LINE__, error.message); 01686 dbus_message_unref (message); 01687 return FALSE; 01688 } 01689 if (reply == NULL) { 01690 dbus_message_unref (message); 01691 return FALSE; 01692 } 01693 01694 dbus_message_unref (message); 01695 dbus_message_unref (reply); 01696 return TRUE; 01697 } 01698 01705 dbus_bool_t 01706 hal_device_exists (LibHalContext *ctx, const char *udi) 01707 { 01708 DBusError error; 01709 DBusMessage *message; 01710 DBusMessage *reply; 01711 DBusMessageIter iter; 01712 dbus_bool_t value; 01713 01714 message = dbus_message_new_method_call ("org.freedesktop.Hal", 01715 "/org/freedesktop/Hal/Manager", 01716 "org.freedesktop.Hal.Manager", 01717 "DeviceExists"); 01718 if (message == NULL) { 01719 fprintf (stderr, 01720 "%s %d : Couldn't allocate D-BUS message\n", 01721 __FILE__, __LINE__); 01722 return FALSE; 01723 } 01724 01725 dbus_message_iter_init (message, &iter); 01726 dbus_message_iter_append_string (&iter, udi); 01727 01728 dbus_error_init (&error); 01729 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 01730 message, -1, 01731 &error); 01732 if (dbus_error_is_set (&error)) { 01733 fprintf (stderr, "%s %d : Error sending msg: %s\n", 01734 __FILE__, __LINE__, error.message); 01735 dbus_message_unref (message); 01736 return FALSE; 01737 } 01738 if (reply == NULL) { 01739 dbus_message_unref (message); 01740 return FALSE; 01741 } 01742 01743 dbus_message_iter_init (reply, &iter); 01744 01745 /* now analyze reply */ 01746 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_BOOLEAN) { 01747 fprintf (stderr, 01748 "%s %d : expected a bool in reply to DeviceExists\n", 01749 __FILE__, __LINE__); 01750 dbus_message_unref (message); 01751 dbus_message_unref (reply); 01752 return FALSE; 01753 } 01754 01755 value = dbus_message_iter_get_boolean (&iter); 01756 01757 dbus_message_unref (message); 01758 dbus_message_unref (reply); 01759 return value; 01760 } 01761 01769 dbus_bool_t 01770 hal_device_property_exists (LibHalContext *ctx, 01771 const char *udi, const char *key) 01772 { 01773 DBusError error; 01774 DBusMessage *message; 01775 DBusMessage *reply; 01776 DBusMessageIter iter; 01777 dbus_bool_t value; 01778 01779 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, 01780 "org.freedesktop.Hal.Device", 01781 "PropertyExists"); 01782 if (message == NULL) { 01783 fprintf (stderr, 01784 "%s %d : Couldn't allocate D-BUS message\n", 01785 __FILE__, __LINE__); 01786 return FALSE; 01787 } 01788 01789 dbus_message_iter_init (message, &iter); 01790 dbus_message_iter_append_string (&iter, key); 01791 01792 dbus_error_init (&error); 01793 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 01794 message, -1, 01795 &error); 01796 if (dbus_error_is_set (&error)) { 01797 fprintf (stderr, "%s %d : Error sending msg: %s\n", 01798 __FILE__, __LINE__, error.message); 01799 dbus_message_unref (message); 01800 return FALSE; 01801 } 01802 if (reply == NULL) { 01803 dbus_message_unref (message); 01804 return FALSE; 01805 } 01806 01807 dbus_message_iter_init (reply, &iter); 01808 01809 /* now analyse reply */ 01810 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_BOOLEAN) { 01811 fprintf (stderr, "%s %d : expected a bool in reply to " 01812 "PropertyExists\n", __FILE__, __LINE__); 01813 dbus_message_unref (message); 01814 dbus_message_unref (reply); 01815 return FALSE; 01816 } 01817 01818 value = dbus_message_iter_get_boolean (&iter); 01819 01820 dbus_message_unref (message); 01821 dbus_message_unref (reply); 01822 return value; 01823 } 01824 01832 dbus_bool_t 01833 hal_agent_merge_properties (LibHalContext *ctx, 01834 const char *target_udi, const char *source_udi) 01835 { 01836 DBusError error; 01837 DBusMessage *message; 01838 DBusMessage *reply; 01839 DBusMessageIter iter; 01840 01841 message = dbus_message_new_method_call ("org.freedesktop.Hal", 01842 "/org/freedesktop/Hal/Manager", 01843 "org.freedesktop.Hal.AgentManager", 01844 "MergeProperties"); 01845 if (message == NULL) { 01846 fprintf (stderr, 01847 "%s %d : Couldn't allocate D-BUS message\n", 01848 __FILE__, __LINE__); 01849 return FALSE; 01850 } 01851 01852 dbus_message_iter_init (message, &iter); 01853 dbus_message_iter_append_string (&iter, target_udi); 01854 dbus_message_iter_append_string (&iter, source_udi); 01855 01856 dbus_error_init (&error); 01857 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 01858 message, -1, 01859 &error); 01860 if (dbus_error_is_set (&error)) { 01861 if (dbus_error_has_name 01862 (&error, "org.freedesktop.Hal.NoSuchDevice")) 01863 return FALSE; 01864 fprintf (stderr, "%s %d : Error sending msg: %s\n", 01865 __FILE__, __LINE__, error.message); 01866 dbus_message_unref (message); 01867 return FALSE; 01868 } 01869 if (reply == NULL) { 01870 dbus_message_unref (message); 01871 return FALSE; 01872 } 01873 01874 dbus_message_unref (message); 01875 dbus_message_unref (reply); 01876 return TRUE; 01877 } 01878 01898 dbus_bool_t 01899 hal_agent_device_matches (LibHalContext *ctx, 01900 const char *udi1, const char *udi2, 01901 const char *property_namespace) 01902 { 01903 DBusError error; 01904 DBusMessage *message; 01905 DBusMessage *reply; 01906 DBusMessageIter iter; 01907 dbus_bool_t value; 01908 01909 message = dbus_message_new_method_call ("org.freedesktop.Hal", 01910 "/org/freedesktop/Hal/Manager", 01911 "org.freedesktop.Hal.AgentManager", 01912 "DeviceMatches"); 01913 if (message == NULL) { 01914 fprintf (stderr, 01915 "%s %d : Couldn't allocate D-BUS message\n", 01916 __FILE__, __LINE__); 01917 return FALSE; 01918 } 01919 01920 dbus_message_iter_init (message, &iter); 01921 dbus_message_iter_append_string (&iter, udi1); 01922 dbus_message_iter_append_string (&iter, udi2); 01923 dbus_message_iter_append_string (&iter, property_namespace); 01924 01925 dbus_error_init (&error); 01926 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 01927 message, -1, 01928 &error); 01929 if (dbus_error_is_set (&error)) { 01930 fprintf (stderr, "%s %d : Error sending msg: %s\n", 01931 __FILE__, __LINE__, error.message); 01932 dbus_message_unref (message); 01933 return FALSE; 01934 } 01935 if (reply == NULL) { 01936 dbus_message_unref (message); 01937 return FALSE; 01938 } 01939 /* now analyse reply */ 01940 dbus_message_iter_init (reply, &iter); 01941 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_BOOLEAN) { 01942 fprintf (stderr, 01943 "%s %d : expected a bool in reply to DeviceMatches\n", 01944 __FILE__, __LINE__); 01945 dbus_message_unref (message); 01946 dbus_message_unref (reply); 01947 return FALSE; 01948 } 01949 01950 value = dbus_message_iter_get_boolean (&iter); 01951 01952 dbus_message_unref (message); 01953 dbus_message_unref (reply); 01954 return value; 01955 } 01956 01962 void 01963 hal_device_print (LibHalContext *ctx, const char *udi) 01964 { 01965 int type; 01966 char *key; 01967 LibHalPropertySet *pset; 01968 LibHalPropertySetIterator i; 01969 01970 printf ("device_id = %s\n", udi); 01971 01972 pset = hal_device_get_all_properties (ctx, udi); 01973 01974 for (hal_psi_init (&i, pset); hal_psi_has_more (&i); 01975 hal_psi_next (&i)) { 01976 type = hal_psi_get_type (&i); 01977 key = hal_psi_get_key (&i); 01978 switch (type) { 01979 case DBUS_TYPE_STRING: 01980 printf (" %s = %s (string)\n", key, 01981 hal_psi_get_string (&i)); 01982 break; 01983 case DBUS_TYPE_INT32: 01984 printf (" %s = %d = 0x%x (int)\n", key, 01985 hal_psi_get_int (&i), 01986 hal_psi_get_int (&i)); 01987 break; 01988 case DBUS_TYPE_UINT64: 01989 printf (" %s = %lld = 0x%llx (uint64)\n", key, 01990 hal_psi_get_uint64 (&i), 01991 hal_psi_get_uint64 (&i)); 01992 break; 01993 case DBUS_TYPE_BOOLEAN: 01994 printf (" %s = %s (bool)\n", key, 01995 (hal_psi_get_bool (&i) ? "true" : 01996 "false")); 01997 break; 01998 case DBUS_TYPE_DOUBLE: 01999 printf (" %s = %g (double)\n", key, 02000 hal_psi_get_double (&i)); 02001 break; 02002 default: 02003 printf (" *** unknown type for key %s\n", key); 02004 break; 02005 } 02006 } 02007 hal_free_property_set (pset); 02008 } 02009 02020 char ** 02021 hal_manager_find_device_string_match (LibHalContext *ctx, 02022 const char *key, 02023 const char *value, int *num_devices) 02024 { 02025 int i; 02026 DBusError error; 02027 DBusMessage *message; 02028 DBusMessage *reply; 02029 DBusMessageIter iter; 02030 char **device_names; 02031 char **hal_device_names; 02032 02033 message = dbus_message_new_method_call ("org.freedesktop.Hal", 02034 "/org/freedesktop/Hal/Manager", 02035 "org.freedesktop.Hal.Manager", 02036 "FindDeviceStringMatch"); 02037 if (message == NULL) { 02038 fprintf (stderr, 02039 "%s %d : Couldn't allocate D-BUS message\n", 02040 __FILE__, __LINE__); 02041 return NULL; 02042 } 02043 02044 dbus_message_iter_init (message, &iter); 02045 dbus_message_iter_append_string (&iter, key); 02046 dbus_message_iter_append_string (&iter, value); 02047 02048 dbus_error_init (&error); 02049 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 02050 message, -1, 02051 &error); 02052 if (dbus_error_is_set (&error)) { 02053 fprintf (stderr, "%s %d : Error sending msg: %s\n", 02054 __FILE__, __LINE__, error.message); 02055 dbus_message_unref (message); 02056 return NULL; 02057 } 02058 if (reply == NULL) { 02059 dbus_message_unref (message); 02060 return NULL; 02061 } 02062 /* now analyse reply */ 02063 dbus_message_iter_init (reply, &iter); 02064 if (!dbus_message_iter_get_string_array (&iter, 02065 &device_names, 02066 num_devices)) { 02067 fprintf (stderr, "%s %d : wrong reply from hald\n", 02068 __FILE__, __LINE__); 02069 return NULL; 02070 } 02071 02072 dbus_message_unref (message); 02073 dbus_message_unref (reply); 02074 02075 /* Have to convert from dbus string array to hal string array 02076 * since we can't poke at the dbus string array for the reason 02077 * that d-bus use their own memory allocation scheme 02078 */ 02079 hal_device_names = malloc (sizeof (char *) * ((*num_devices) + 1)); 02080 if (hal_device_names == NULL) 02081 return NULL; 02084 for (i = 0; i < (*num_devices); i++) { 02085 hal_device_names[i] = strdup (device_names[i]); 02086 if (hal_device_names[i] == NULL) 02087 return NULL; 02089 } 02090 hal_device_names[i] = NULL; 02091 02092 dbus_free_string_array (device_names); 02093 02094 return hal_device_names; 02095 } 02096 02097 02106 dbus_bool_t 02107 hal_device_add_capability (LibHalContext *ctx, 02108 const char *udi, const char *capability) 02109 { 02110 DBusError error; 02111 DBusMessage *message; 02112 DBusMessage *reply; 02113 DBusMessageIter iter; 02114 02115 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, 02116 "org.freedesktop.Hal.Device", 02117 "AddCapability"); 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 (message, &iter); 02126 dbus_message_iter_append_string (&iter, capability); 02127 02128 dbus_error_init (&error); 02129 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 02130 message, -1, 02131 &error); 02132 if (dbus_error_is_set (&error)) { 02133 fprintf (stderr, "%s %d: %s raised\n\"%s\"\n\n", __FILE__, 02134 __LINE__, error.name, error.message); 02135 dbus_message_unref (message); 02136 return FALSE; 02137 } 02138 02139 if (reply == NULL) { 02140 dbus_message_unref (message); 02141 return FALSE; 02142 } 02143 02144 dbus_message_unref (reply); 02145 dbus_message_unref (message); 02146 return TRUE; 02147 } 02148 02158 dbus_bool_t 02159 hal_device_query_capability (LibHalContext *ctx, 02160 const char *udi, const char *capability) 02161 { 02162 char *caps; 02163 02164 caps = hal_device_get_property_string (ctx, udi, "info.capabilities"); 02165 02166 if (caps != NULL) 02167 if (strstr (caps, capability) != NULL) 02168 return TRUE; 02169 02170 return FALSE; 02171 } 02172 02181 char ** 02182 hal_find_device_by_capability (LibHalContext *ctx, 02183 const char *capability, int *num_devices) 02184 { 02185 int i; 02186 DBusError error; 02187 DBusMessage *message; 02188 DBusMessage *reply; 02189 DBusMessageIter iter; 02190 char **device_names; 02191 char **hal_device_names; 02192 02193 message = dbus_message_new_method_call ("org.freedesktop.Hal", 02194 "/org/freedesktop/Hal/Manager", 02195 "org.freedesktop.Hal.Manager", 02196 "FindDeviceByCapability"); 02197 if (message == NULL) { 02198 fprintf (stderr, 02199 "%s %d : Couldn't allocate D-BUS message\n", 02200 __FILE__, __LINE__); 02201 return NULL; 02202 } 02203 02204 dbus_message_iter_init (message, &iter); 02205 dbus_message_iter_append_string (&iter, capability); 02206 02207 dbus_error_init (&error); 02208 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 02209 message, -1, 02210 &error); 02211 if (dbus_error_is_set (&error)) { 02212 fprintf (stderr, "%s %d : Error sending msg: %s\n", 02213 __FILE__, __LINE__, error.message); 02214 dbus_message_unref (message); 02215 return NULL; 02216 } 02217 if (reply == NULL) { 02218 dbus_message_unref (message); 02219 return NULL; 02220 } 02221 /* now analyse reply */ 02222 dbus_message_iter_init (reply, &iter); 02223 if (!dbus_message_iter_get_string_array (&iter, 02224 &device_names, 02225 num_devices)) { 02226 fprintf (stderr, "%s %d : wrong reply from hald\n", 02227 __FILE__, __LINE__); 02228 return NULL; 02229 } 02230 02231 dbus_message_unref (message); 02232 dbus_message_unref (reply); 02233 02234 /* Have to convert from dbus string array to hal string array 02235 * since we can't poke at the dbus string array for the reason 02236 * that d-bus use their own memory allocation scheme 02237 */ 02238 hal_device_names = malloc (sizeof (char *) * ((*num_devices) + 1)); 02239 if (hal_device_names == NULL) 02240 return NULL; 02243 for (i = 0; i < (*num_devices); i++) { 02244 hal_device_names[i] = strdup (device_names[i]); 02245 if (hal_device_names[i] == NULL) 02246 return NULL; 02248 } 02249 hal_device_names[i] = NULL; 02250 02251 dbus_free_string_array (device_names); 02252 02253 return hal_device_names; 02254 } 02255 02263 int 02264 hal_device_property_watch_all (LibHalContext *ctx) 02265 { 02266 DBusError error; 02267 02268 dbus_error_init (&error); 02269 02270 dbus_bus_add_match (ctx->connection, 02271 "type='signal'," 02272 "interface='org.freedesktop.Hal.Device'," 02273 "sender='org.freedesktop.Hal'", &error); 02274 if (dbus_error_is_set (&error)) { 02275 fprintf (stderr, "%s %d : Error subscribing to signals, " 02276 "error=%s\r\n", 02277 __FILE__, __LINE__, error.message); 02278 return 1; 02279 } 02280 return 0; 02281 } 02282 02283 02295 int 02296 hal_device_add_property_watch (LibHalContext *ctx, const char *udi) 02297 { 02298 char buf[512]; 02299 DBusError error; 02300 02301 dbus_error_init (&error); 02302 02303 snprintf (buf, 512, 02304 "type='signal'," 02305 "interface='org.freedesktop.Hal.Device'," 02306 "sender='org.freedesktop.Hal'," "path=%s", udi); 02307 02308 dbus_bus_add_match (ctx->connection, buf, &error); 02309 if (dbus_error_is_set (&error)) { 02310 fprintf (stderr, "%s %d : Error subscribing to signals, " 02311 "error=%s\r\n", 02312 __FILE__, __LINE__, error.message); 02313 return 1; 02314 } 02315 return 0; 02316 } 02317 02318 02326 int 02327 hal_device_remove_property_watch (LibHalContext *ctx, const char *udi) 02328 { 02329 char buf[512]; 02330 DBusError error; 02331 02332 dbus_error_init (&error); 02333 02334 snprintf (buf, 512, 02335 "type='signal'," 02336 "interface='org.freedesktop.Hal.Device'," 02337 "sender='org.freedesktop.Hal'," "path=%s", udi); 02338 02339 dbus_bus_remove_match (ctx->connection, buf, &error); 02340 if (dbus_error_is_set (&error)) { 02341 fprintf (stderr, "%s %d : Error unsubscribing to signals, " 02342 "error=%s\r\n", 02343 __FILE__, __LINE__, error.message); 02344 return 1; 02345 } 02346 return 0; 02347 } 02348 02349

Generated on Sat Oct 16 10:08:02 2004 for HAL by doxygen 1.3.7