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

libhal.c

00001 /*************************************************************************** 00002 * CVSID: $Id: libhal.c,v 1.25 2004/09/01 17:38:58 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 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 01380 01392 char * 01393 hal_agent_new_device (LibHalContext *ctx) 01394 { 01395 DBusError error; 01396 DBusMessage *message; 01397 DBusMessage *reply; 01398 DBusMessageIter iter; 01399 char *value; 01400 char *dbus_str; 01401 01402 message = dbus_message_new_method_call ("org.freedesktop.Hal", 01403 "/org/freedesktop/Hal/Manager", 01404 "org.freedesktop.Hal.AgentManager", 01405 "NewDevice"); 01406 if (message == NULL) { 01407 fprintf (stderr, 01408 "%s %d : Couldn't allocate D-BUS message\n", 01409 __FILE__, __LINE__); 01410 return NULL; 01411 } 01412 01413 dbus_error_init (&error); 01414 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 01415 message, -1, 01416 &error); 01417 if (dbus_error_is_set (&error)) { 01418 fprintf (stderr, "%s %d : Error sending msg: %s\n", 01419 __FILE__, __LINE__, error.message); 01420 dbus_message_unref (message); 01421 return NULL; 01422 } 01423 if (reply == NULL) { 01424 dbus_message_unref (message); 01425 return NULL; 01426 } 01427 01428 dbus_message_iter_init (reply, &iter); 01429 01430 /* now analyze reply */ 01431 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING) { 01432 fprintf (stderr, 01433 "%s %d : expected a string in reply to NewDevice\n", 01434 __FILE__, __LINE__); 01435 dbus_message_unref (message); 01436 dbus_message_unref (reply); 01437 return NULL; 01438 } 01439 01440 dbus_str = dbus_message_iter_get_string (&iter); 01441 value = (char *) ((dbus_str != NULL) ? strdup (dbus_str) : NULL); 01442 if (value == NULL) { 01443 fprintf (stderr, "%s %d : error allocating memory\n", 01444 __FILE__, __LINE__); 01446 return NULL; 01447 } 01448 dbus_free (dbus_str); 01449 01450 dbus_message_unref (message); 01451 dbus_message_unref (reply); 01452 return value; 01453 } 01454 01455 01474 dbus_bool_t 01475 hal_agent_commit_to_gdl (LibHalContext *ctx, 01476 const char *temp_udi, const char *udi) 01477 { 01478 DBusError error; 01479 DBusMessage *message; 01480 DBusMessage *reply; 01481 DBusMessageIter iter; 01482 01483 message = dbus_message_new_method_call ("org.freedesktop.Hal", 01484 "/org/freedesktop/Hal/Manager", 01485 "org.freedesktop.Hal.AgentManager", 01486 "CommitToGdl"); 01487 if (message == NULL) { 01488 fprintf (stderr, 01489 "%s %d : Couldn't allocate D-BUS message\n", 01490 __FILE__, __LINE__); 01491 return FALSE; 01492 } 01493 01494 dbus_message_iter_init (message, &iter); 01495 dbus_message_iter_append_string (&iter, temp_udi); 01496 dbus_message_iter_append_string (&iter, udi); 01497 01498 dbus_error_init (&error); 01499 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 01500 message, -1, 01501 &error); 01502 if (dbus_error_is_set (&error)) { 01503 if (dbus_error_has_name 01504 (&error, "org.freedesktop.Hal.UdiInUse")) 01505 return FALSE; 01506 fprintf (stderr, "%s %d : Error sending msg: %s\n", 01507 __FILE__, __LINE__, error.message); 01508 dbus_message_unref (message); 01509 return FALSE; 01510 } 01511 if (reply == NULL) { 01512 dbus_message_unref (message); 01513 return FALSE; 01514 } 01515 01516 dbus_message_unref (message); 01517 dbus_message_unref (reply); 01518 return TRUE; 01519 } 01520 01532 dbus_bool_t 01533 hal_agent_remove_device (LibHalContext *ctx, const char *udi) 01534 { 01535 DBusError error; 01536 DBusMessage *message; 01537 DBusMessage *reply; 01538 DBusMessageIter iter; 01539 01540 message = dbus_message_new_method_call ("org.freedesktop.Hal", 01541 "/org/freedesktop/Hal/Manager", 01542 "org.freedesktop.Hal.AgentManager", 01543 "Remove"); 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, udi); 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_unref (message); 01570 dbus_message_unref (reply); 01571 return TRUE; 01572 } 01573 01580 dbus_bool_t 01581 hal_device_exists (LibHalContext *ctx, const char *udi) 01582 { 01583 DBusError error; 01584 DBusMessage *message; 01585 DBusMessage *reply; 01586 DBusMessageIter iter; 01587 dbus_bool_t value; 01588 01589 message = dbus_message_new_method_call ("org.freedesktop.Hal", 01590 "/org/freedesktop/Hal/Manager", 01591 "org.freedesktop.Hal.Manager", 01592 "DeviceExists"); 01593 if (message == NULL) { 01594 fprintf (stderr, 01595 "%s %d : Couldn't allocate D-BUS message\n", 01596 __FILE__, __LINE__); 01597 return FALSE; 01598 } 01599 01600 dbus_message_iter_init (message, &iter); 01601 dbus_message_iter_append_string (&iter, udi); 01602 01603 dbus_error_init (&error); 01604 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 01605 message, -1, 01606 &error); 01607 if (dbus_error_is_set (&error)) { 01608 fprintf (stderr, "%s %d : Error sending msg: %s\n", 01609 __FILE__, __LINE__, error.message); 01610 dbus_message_unref (message); 01611 return FALSE; 01612 } 01613 if (reply == NULL) { 01614 dbus_message_unref (message); 01615 return FALSE; 01616 } 01617 01618 dbus_message_iter_init (reply, &iter); 01619 01620 /* now analyze reply */ 01621 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_BOOLEAN) { 01622 fprintf (stderr, 01623 "%s %d : expected a bool in reply to DeviceExists\n", 01624 __FILE__, __LINE__); 01625 dbus_message_unref (message); 01626 dbus_message_unref (reply); 01627 return FALSE; 01628 } 01629 01630 value = dbus_message_iter_get_boolean (&iter); 01631 01632 dbus_message_unref (message); 01633 dbus_message_unref (reply); 01634 return value; 01635 } 01636 01644 dbus_bool_t 01645 hal_device_property_exists (LibHalContext *ctx, 01646 const char *udi, const char *key) 01647 { 01648 DBusError error; 01649 DBusMessage *message; 01650 DBusMessage *reply; 01651 DBusMessageIter iter; 01652 dbus_bool_t value; 01653 01654 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, 01655 "org.freedesktop.Hal.Device", 01656 "PropertyExists"); 01657 if (message == NULL) { 01658 fprintf (stderr, 01659 "%s %d : Couldn't allocate D-BUS message\n", 01660 __FILE__, __LINE__); 01661 return FALSE; 01662 } 01663 01664 dbus_message_iter_init (message, &iter); 01665 dbus_message_iter_append_string (&iter, key); 01666 01667 dbus_error_init (&error); 01668 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 01669 message, -1, 01670 &error); 01671 if (dbus_error_is_set (&error)) { 01672 fprintf (stderr, "%s %d : Error sending msg: %s\n", 01673 __FILE__, __LINE__, error.message); 01674 dbus_message_unref (message); 01675 return FALSE; 01676 } 01677 if (reply == NULL) { 01678 dbus_message_unref (message); 01679 return FALSE; 01680 } 01681 01682 dbus_message_iter_init (reply, &iter); 01683 01684 /* now analyse reply */ 01685 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_BOOLEAN) { 01686 fprintf (stderr, "%s %d : expected a bool in reply to " 01687 "PropertyExists\n", __FILE__, __LINE__); 01688 dbus_message_unref (message); 01689 dbus_message_unref (reply); 01690 return FALSE; 01691 } 01692 01693 value = dbus_message_iter_get_boolean (&iter); 01694 01695 dbus_message_unref (message); 01696 dbus_message_unref (reply); 01697 return value; 01698 } 01699 01707 dbus_bool_t 01708 hal_agent_merge_properties (LibHalContext *ctx, 01709 const char *target_udi, const char *source_udi) 01710 { 01711 DBusError error; 01712 DBusMessage *message; 01713 DBusMessage *reply; 01714 DBusMessageIter iter; 01715 01716 message = dbus_message_new_method_call ("org.freedesktop.Hal", 01717 "/org/freedesktop/Hal/Manager", 01718 "org.freedesktop.Hal.AgentManager", 01719 "MergeProperties"); 01720 if (message == NULL) { 01721 fprintf (stderr, 01722 "%s %d : Couldn't allocate D-BUS message\n", 01723 __FILE__, __LINE__); 01724 return FALSE; 01725 } 01726 01727 dbus_message_iter_init (message, &iter); 01728 dbus_message_iter_append_string (&iter, target_udi); 01729 dbus_message_iter_append_string (&iter, source_udi); 01730 01731 dbus_error_init (&error); 01732 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 01733 message, -1, 01734 &error); 01735 if (dbus_error_is_set (&error)) { 01736 if (dbus_error_has_name 01737 (&error, "org.freedesktop.Hal.NoSuchDevice")) 01738 return FALSE; 01739 fprintf (stderr, "%s %d : Error sending msg: %s\n", 01740 __FILE__, __LINE__, error.message); 01741 dbus_message_unref (message); 01742 return FALSE; 01743 } 01744 if (reply == NULL) { 01745 dbus_message_unref (message); 01746 return FALSE; 01747 } 01748 01749 dbus_message_unref (message); 01750 dbus_message_unref (reply); 01751 return TRUE; 01752 } 01753 01773 dbus_bool_t 01774 hal_agent_device_matches (LibHalContext *ctx, 01775 const char *udi1, const char *udi2, 01776 const char *property_namespace) 01777 { 01778 DBusError error; 01779 DBusMessage *message; 01780 DBusMessage *reply; 01781 DBusMessageIter iter; 01782 dbus_bool_t value; 01783 01784 message = dbus_message_new_method_call ("org.freedesktop.Hal", 01785 "/org/freedesktop/Hal/Manager", 01786 "org.freedesktop.Hal.AgentManager", 01787 "DeviceMatches"); 01788 if (message == NULL) { 01789 fprintf (stderr, 01790 "%s %d : Couldn't allocate D-BUS message\n", 01791 __FILE__, __LINE__); 01792 return FALSE; 01793 } 01794 01795 dbus_message_iter_init (message, &iter); 01796 dbus_message_iter_append_string (&iter, udi1); 01797 dbus_message_iter_append_string (&iter, udi2); 01798 dbus_message_iter_append_string (&iter, property_namespace); 01799 01800 dbus_error_init (&error); 01801 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 01802 message, -1, 01803 &error); 01804 if (dbus_error_is_set (&error)) { 01805 fprintf (stderr, "%s %d : Error sending msg: %s\n", 01806 __FILE__, __LINE__, error.message); 01807 dbus_message_unref (message); 01808 return FALSE; 01809 } 01810 if (reply == NULL) { 01811 dbus_message_unref (message); 01812 return FALSE; 01813 } 01814 /* now analyse reply */ 01815 dbus_message_iter_init (reply, &iter); 01816 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_BOOLEAN) { 01817 fprintf (stderr, 01818 "%s %d : expected a bool in reply to DeviceMatches\n", 01819 __FILE__, __LINE__); 01820 dbus_message_unref (message); 01821 dbus_message_unref (reply); 01822 return FALSE; 01823 } 01824 01825 value = dbus_message_iter_get_boolean (&iter); 01826 01827 dbus_message_unref (message); 01828 dbus_message_unref (reply); 01829 return value; 01830 } 01831 01837 void 01838 hal_device_print (LibHalContext *ctx, const char *udi) 01839 { 01840 int type; 01841 char *key; 01842 LibHalPropertySet *pset; 01843 LibHalPropertySetIterator i; 01844 01845 printf ("device_id = %s\n", udi); 01846 01847 pset = hal_device_get_all_properties (ctx, udi); 01848 01849 for (hal_psi_init (&i, pset); hal_psi_has_more (&i); 01850 hal_psi_next (&i)) { 01851 type = hal_psi_get_type (&i); 01852 key = hal_psi_get_key (&i); 01853 switch (type) { 01854 case DBUS_TYPE_STRING: 01855 printf (" %s = %s (string)\n", key, 01856 hal_psi_get_string (&i)); 01857 break; 01858 case DBUS_TYPE_INT32: 01859 printf (" %s = %d = 0x%x (int)\n", key, 01860 hal_psi_get_int (&i), 01861 hal_psi_get_int (&i)); 01862 break; 01863 case DBUS_TYPE_UINT64: 01864 printf (" %s = %lld = 0x%llx (uint64)\n", key, 01865 hal_psi_get_uint64 (&i), 01866 hal_psi_get_uint64 (&i)); 01867 break; 01868 case DBUS_TYPE_BOOLEAN: 01869 printf (" %s = %s (bool)\n", key, 01870 (hal_psi_get_bool (&i) ? "true" : 01871 "false")); 01872 break; 01873 case DBUS_TYPE_DOUBLE: 01874 printf (" %s = %g (double)\n", key, 01875 hal_psi_get_double (&i)); 01876 break; 01877 default: 01878 printf (" *** unknown type for key %s\n", key); 01879 break; 01880 } 01881 } 01882 hal_free_property_set (pset); 01883 } 01884 01895 char ** 01896 hal_manager_find_device_string_match (LibHalContext *ctx, 01897 const char *key, 01898 const char *value, int *num_devices) 01899 { 01900 int i; 01901 DBusError error; 01902 DBusMessage *message; 01903 DBusMessage *reply; 01904 DBusMessageIter iter; 01905 char **device_names; 01906 char **hal_device_names; 01907 01908 message = dbus_message_new_method_call ("org.freedesktop.Hal", 01909 "/org/freedesktop/Hal/Manager", 01910 "org.freedesktop.Hal.Manager", 01911 "FindDeviceStringMatch"); 01912 if (message == NULL) { 01913 fprintf (stderr, 01914 "%s %d : Couldn't allocate D-BUS message\n", 01915 __FILE__, __LINE__); 01916 return NULL; 01917 } 01918 01919 dbus_message_iter_init (message, &iter); 01920 dbus_message_iter_append_string (&iter, key); 01921 dbus_message_iter_append_string (&iter, value); 01922 01923 dbus_error_init (&error); 01924 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 01925 message, -1, 01926 &error); 01927 if (dbus_error_is_set (&error)) { 01928 fprintf (stderr, "%s %d : Error sending msg: %s\n", 01929 __FILE__, __LINE__, error.message); 01930 dbus_message_unref (message); 01931 return NULL; 01932 } 01933 if (reply == NULL) { 01934 dbus_message_unref (message); 01935 return NULL; 01936 } 01937 /* now analyse reply */ 01938 dbus_message_iter_init (reply, &iter); 01939 if (!dbus_message_iter_get_string_array (&iter, 01940 &device_names, 01941 num_devices)) { 01942 fprintf (stderr, "%s %d : wrong reply from hald\n", 01943 __FILE__, __LINE__); 01944 return NULL; 01945 } 01946 01947 dbus_message_unref (message); 01948 dbus_message_unref (reply); 01949 01950 /* Have to convert from dbus string array to hal string array 01951 * since we can't poke at the dbus string array for the reason 01952 * that d-bus use their own memory allocation scheme 01953 */ 01954 hal_device_names = malloc (sizeof (char *) * ((*num_devices) + 1)); 01955 if (hal_device_names == NULL) 01956 return NULL; 01959 for (i = 0; i < (*num_devices); i++) { 01960 hal_device_names[i] = strdup (device_names[i]); 01961 if (hal_device_names[i] == NULL) 01962 return NULL; 01964 } 01965 hal_device_names[i] = NULL; 01966 01967 dbus_free_string_array (device_names); 01968 01969 return hal_device_names; 01970 } 01971 01972 01981 dbus_bool_t 01982 hal_device_add_capability (LibHalContext *ctx, 01983 const char *udi, const char *capability) 01984 { 01985 DBusError error; 01986 DBusMessage *message; 01987 DBusMessage *reply; 01988 DBusMessageIter iter; 01989 01990 message = dbus_message_new_method_call ("org.freedesktop.Hal", udi, 01991 "org.freedesktop.Hal.Device", 01992 "AddCapability"); 01993 if (message == NULL) { 01994 fprintf (stderr, 01995 "%s %d : Couldn't allocate D-BUS message\n", 01996 __FILE__, __LINE__); 01997 return FALSE; 01998 } 01999 02000 dbus_message_iter_init (message, &iter); 02001 dbus_message_iter_append_string (&iter, capability); 02002 02003 dbus_error_init (&error); 02004 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 02005 message, -1, 02006 &error); 02007 if (dbus_error_is_set (&error)) { 02008 fprintf (stderr, "%s %d: %s raised\n\"%s\"\n\n", __FILE__, 02009 __LINE__, error.name, error.message); 02010 dbus_message_unref (message); 02011 return FALSE; 02012 } 02013 02014 if (reply == NULL) { 02015 dbus_message_unref (message); 02016 return FALSE; 02017 } 02018 02019 dbus_message_unref (reply); 02020 dbus_message_unref (message); 02021 return TRUE; 02022 } 02023 02033 dbus_bool_t 02034 hal_device_query_capability (LibHalContext *ctx, 02035 const char *udi, const char *capability) 02036 { 02037 char *caps; 02038 02039 caps = hal_device_get_property_string (ctx, udi, "info.capabilities"); 02040 02041 if (caps != NULL) 02042 if (strstr (caps, capability) != NULL) 02043 return TRUE; 02044 02045 return FALSE; 02046 } 02047 02056 char ** 02057 hal_find_device_by_capability (LibHalContext *ctx, 02058 const char *capability, int *num_devices) 02059 { 02060 int i; 02061 DBusError error; 02062 DBusMessage *message; 02063 DBusMessage *reply; 02064 DBusMessageIter iter; 02065 char **device_names; 02066 char **hal_device_names; 02067 02068 message = dbus_message_new_method_call ("org.freedesktop.Hal", 02069 "/org/freedesktop/Hal/Manager", 02070 "org.freedesktop.Hal.Manager", 02071 "FindDeviceByCapability"); 02072 if (message == NULL) { 02073 fprintf (stderr, 02074 "%s %d : Couldn't allocate D-BUS message\n", 02075 __FILE__, __LINE__); 02076 return NULL; 02077 } 02078 02079 dbus_message_iter_init (message, &iter); 02080 dbus_message_iter_append_string (&iter, capability); 02081 02082 dbus_error_init (&error); 02083 reply = dbus_connection_send_with_reply_and_block (ctx->connection, 02084 message, -1, 02085 &error); 02086 if (dbus_error_is_set (&error)) { 02087 fprintf (stderr, "%s %d : Error sending msg: %s\n", 02088 __FILE__, __LINE__, error.message); 02089 dbus_message_unref (message); 02090 return NULL; 02091 } 02092 if (reply == NULL) { 02093 dbus_message_unref (message); 02094 return NULL; 02095 } 02096 /* now analyse reply */ 02097 dbus_message_iter_init (reply, &iter); 02098 if (!dbus_message_iter_get_string_array (&iter, 02099 &device_names, 02100 num_devices)) { 02101 fprintf (stderr, "%s %d : wrong reply from hald\n", 02102 __FILE__, __LINE__); 02103 return NULL; 02104 } 02105 02106 dbus_message_unref (message); 02107 dbus_message_unref (reply); 02108 02109 /* Have to convert from dbus string array to hal string array 02110 * since we can't poke at the dbus string array for the reason 02111 * that d-bus use their own memory allocation scheme 02112 */ 02113 hal_device_names = malloc (sizeof (char *) * ((*num_devices) + 1)); 02114 if (hal_device_names == NULL) 02115 return NULL; 02118 for (i = 0; i < (*num_devices); i++) { 02119 hal_device_names[i] = strdup (device_names[i]); 02120 if (hal_device_names[i] == NULL) 02121 return NULL; 02123 } 02124 hal_device_names[i] = NULL; 02125 02126 dbus_free_string_array (device_names); 02127 02128 return hal_device_names; 02129 } 02130 02138 int 02139 hal_device_property_watch_all (LibHalContext *ctx) 02140 { 02141 DBusError error; 02142 02143 dbus_error_init (&error); 02144 02145 dbus_bus_add_match (ctx->connection, 02146 "type='signal'," 02147 "interface='org.freedesktop.Hal.Device'," 02148 "sender='org.freedesktop.Hal'", &error); 02149 if (dbus_error_is_set (&error)) { 02150 fprintf (stderr, "%s %d : Error subscribing to signals, " 02151 "error=%s\r\n", 02152 __FILE__, __LINE__, error.message); 02153 return 1; 02154 } 02155 return 0; 02156 } 02157 02158 02170 int 02171 hal_device_add_property_watch (LibHalContext *ctx, const char *udi) 02172 { 02173 char buf[512]; 02174 DBusError error; 02175 02176 dbus_error_init (&error); 02177 02178 snprintf (buf, 512, 02179 "type='signal'," 02180 "interface='org.freedesktop.Hal.Device'," 02181 "sender='org.freedesktop.Hal'," "path=%s", udi); 02182 02183 dbus_bus_add_match (ctx->connection, buf, &error); 02184 if (dbus_error_is_set (&error)) { 02185 fprintf (stderr, "%s %d : Error subscribing to signals, " 02186 "error=%s\r\n", 02187 __FILE__, __LINE__, error.message); 02188 return 1; 02189 } 02190 return 0; 02191 } 02192 02193 02201 int 02202 hal_device_remove_property_watch (LibHalContext *ctx, const char *udi) 02203 { 02204 char buf[512]; 02205 DBusError error; 02206 02207 dbus_error_init (&error); 02208 02209 snprintf (buf, 512, 02210 "type='signal'," 02211 "interface='org.freedesktop.Hal.Device'," 02212 "sender='org.freedesktop.Hal'," "path=%s", udi); 02213 02214 dbus_bus_remove_match (ctx->connection, buf, &error); 02215 if (dbus_error_is_set (&error)) { 02216 fprintf (stderr, "%s %d : Error unsubscribing to signals, " 02217 "error=%s\r\n", 02218 __FILE__, __LINE__, error.message); 02219 return 1; 02220 } 02221 return 0; 02222 } 02223 02224

Generated on Wed Sep 8 21:23:19 2004 for HAL by doxygen 1.3.8