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

libhal.c

00001 /***************************************************************************
00002  * CVSID: $Id: libhal.c,v 1.16 2004/01/13 02:01:04 david Exp $
00003  *
00004  * libhal.c : HAL daemon C convenience library headers
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 hal_free_string_array(char** str_array)
00050 {
00051     if( str_array!=NULL )
00052     {
00053         int i;
00054 
00055         for(i=0; str_array[i]!=NULL; i++)
00056         {
00057             free(str_array[i]);
00058         }
00059         free(str_array);
00060     }
00061 }
00062 
00067 void hal_free_string(char* str)
00068 {
00070     free(str);
00071 }
00072 
00073 
00075 struct LibHalPropertySet_s
00076 {
00077     unsigned int num_properties;     
00078     LibHalProperty* properties_head; 
00080 };
00081 
00083 struct LibHalProperty_s
00084 {
00085     int type;                        
00086     char* key;                       
00089     union
00090     {
00091         char* str_value;             
00092         dbus_int32_t int_value;      
00093         double double_value;         
00094         dbus_bool_t bool_value;      
00095     };
00096 
00097     LibHalProperty* next;            
00099 };
00100 
00101 static DBusConnection* connection;
00102 static dbus_bool_t is_initialized = FALSE;
00103 static dbus_bool_t cache_enabled = FALSE;
00104 static const LibHalFunctions* functions;
00105 
00112 LibHalPropertySet* hal_device_get_all_properties(const char* udi)
00113 {
00114     DBusError error;
00115     DBusMessage* message;
00116     DBusMessage* reply;
00117     DBusMessageIter iter;
00118     DBusMessageIter dict_iter;
00119     LibHalPropertySet* result;
00120     LibHalProperty** pn;
00121 
00122     message = dbus_message_new_method_call("org.freedesktop.Hal", udi,
00123                                            "org.freedesktop.Hal.Device",
00124                                            "GetAllProperties");
00125     if( message==NULL )
00126     {
00127         fprintf(stderr, "%s %d : Couldn't allocate D-BUS message\n",
00128                 __FILE__, __LINE__);
00129         return NULL;
00130     }
00131 
00132     dbus_error_init(&error);
00133     reply = dbus_connection_send_with_reply_and_block(connection,
00134                                                       message, -1,
00135                                                       &error);
00136     if( dbus_error_is_set(&error) )
00137     {
00138         fprintf(stderr, "%s %d: %s raised\n\"%s\"\n\n", __FILE__, __LINE__, 
00139                 error.name, error.message);
00140         dbus_message_unref(message);
00141         return NULL;
00142     }
00143 
00144     if( reply==NULL )
00145     {
00146         dbus_message_unref(message);
00147         return NULL;
00148     }
00149 
00150     dbus_message_iter_init(reply, &iter);
00151 
00152     result = malloc(sizeof(LibHalPropertySet));
00153     if( result==NULL )
00154     {
00155         fprintf(stderr, "%s %d : error allocating memory\n", 
00156                 __FILE__, __LINE__);
00157         dbus_message_unref(message);
00158         dbus_message_unref(reply);
00159         return NULL;
00160     }
00161 
00162 /*
00163     result->properties = malloc(sizeof(LibHalProperty)*result->num_properties);
00164     if( result->properties==NULL )
00165     {
00166         // TODO: cleanup
00167         return NULL;
00168     }
00169 */
00170 
00171     pn = &result->properties_head;
00172     result->num_properties = 0;
00173 
00174     dbus_message_iter_init_dict_iterator(&iter, &dict_iter);
00175 
00176     do
00177     {
00178         char* dbus_str;
00179         LibHalProperty* p;
00180 
00181         p = malloc(sizeof(LibHalProperty));
00182         if( p==NULL )
00183         {
00184             fprintf(stderr, "%s %d : error allocating memory\n", 
00185                 __FILE__, __LINE__);
00187             return NULL;
00188         }
00189 
00190         *pn = p;
00191         pn = &p->next;
00192         p->next = NULL;
00193         result->num_properties++;
00194 
00195         dbus_str = dbus_message_iter_get_dict_key(&dict_iter);
00196         p->key = (char*) ((dbus_str!=NULL) ? strdup(dbus_str) : NULL);
00197         if( p->key==NULL )
00198         {
00199             fprintf(stderr, "%s %d : error allocating memory\n", 
00200                     __FILE__, __LINE__);
00202             return NULL;
00203         }
00204         dbus_free(dbus_str);
00205 
00206         p->type = dbus_message_iter_get_arg_type(&dict_iter);
00207 
00208         switch( p->type )
00209         {
00210         case DBUS_TYPE_STRING:
00211             dbus_str = dbus_message_iter_get_string(&dict_iter);
00212             p->str_value = (char*)((dbus_str!=NULL) ? strdup(dbus_str) : NULL);
00213             if( p->str_value==NULL )
00214             {
00215                 fprintf(stderr, "%s %d : error allocating memory\n", 
00216                         __FILE__, __LINE__);
00218                 return NULL;
00219             }
00220             dbus_free(dbus_str);
00221             break;
00222         case DBUS_TYPE_INT32:
00223             p->int_value = dbus_message_iter_get_int32(&dict_iter);
00224             break;
00225         case DBUS_TYPE_DOUBLE:
00226             p->double_value = dbus_message_iter_get_double(&dict_iter);
00227             break;
00228         case DBUS_TYPE_BOOLEAN:
00229             p->bool_value = dbus_message_iter_get_boolean(&dict_iter);
00230             break;
00231 
00232         default:
00233             // TODO: report error
00234             break;
00235         }
00236 
00237         dbus_message_iter_next(&dict_iter);
00238     }
00239     while( dbus_message_iter_has_next(&dict_iter) );
00240 
00241     dbus_message_unref(message);
00242     dbus_message_unref(reply);
00243 
00244     return result;
00245 }
00246 
00251 void hal_free_property_set(LibHalPropertySet* set)
00252 {
00253     LibHalProperty* p;
00254     LibHalProperty* q;
00255 
00256     for(p=set->properties_head; p!=NULL; p=q)
00257     {
00258         free(p->key);
00259         if( p->type==DBUS_TYPE_STRING )
00260             free(p->str_value);
00261         q = p->next;
00262         free(p);
00263     }
00264     free(set);
00265 }
00266 
00272 void hal_psi_init(LibHalPropertySetIterator* iter, LibHalPropertySet* set)
00273 {
00274     iter->set = set;
00275     iter->index = 0;
00276     iter->cur_prop = set->properties_head;
00277 }
00278 
00284 dbus_bool_t hal_psi_has_more(LibHalPropertySetIterator* iter)
00285 {
00286     return iter->index < iter->set->num_properties;
00287 }
00288 
00293 void hal_psi_next(LibHalPropertySetIterator* iter)
00294 {
00295     iter->index++;
00296     iter->cur_prop = iter->cur_prop->next;
00297 }
00298 
00305 int hal_psi_get_type(LibHalPropertySetIterator* iter)
00306 {
00307     return iter->cur_prop->type;
00308 }
00309 
00318 char* hal_psi_get_key(LibHalPropertySetIterator* iter)
00319 {
00320     return iter->cur_prop->key;
00321 }
00322 
00331 char* hal_psi_get_string(LibHalPropertySetIterator* iter)
00332 {
00333     return iter->cur_prop->str_value;
00334 }
00335 
00341 dbus_int32_t hal_psi_get_int(LibHalPropertySetIterator* iter)
00342 {
00343     return iter->cur_prop->int_value;
00344 }
00345 
00351 double hal_psi_get_double(LibHalPropertySetIterator* iter)
00352 {
00353     return iter->cur_prop->double_value;
00354 }
00355 
00361 dbus_bool_t hal_psi_get_bool(LibHalPropertySetIterator* iter)
00362 {
00363     return iter->cur_prop->bool_value;
00364 }
00365 
00366 
00367 static DBusHandlerResult filter_func(DBusConnection* connection,
00368                                      DBusMessage*    message,
00369                                      void*           user_data)
00370 {  
00371     const char* object_path;
00372     DBusError error;
00373 
00374     dbus_error_init(&error);
00375 
00376     object_path = dbus_message_get_path(message);
00377 
00378     /*printf("*** in filter_func, object_path=%s\n", object_path);*/
00379 
00380     if( dbus_message_is_signal(message, "org.freedesktop.Hal.Manager",
00381                                "DeviceAdded") )
00382     {
00383         char* udi;
00384         if( dbus_message_get_args(message, &error, 
00385                                   DBUS_TYPE_STRING, &udi,
00386                                   DBUS_TYPE_INVALID) )
00387         {
00388             if( functions->device_added!=NULL )
00389             {
00390                 functions->device_added(udi);
00391                 dbus_free(udi);
00392             }
00393         }
00394     }
00395     else if( dbus_message_is_signal(message, "org.freedesktop.Hal.Manager",
00396                                     "DeviceRemoved") )
00397     {
00398         char* udi;
00399         if( dbus_message_get_args(message, &error, 
00400                                   DBUS_TYPE_STRING, &udi,
00401                                   DBUS_TYPE_INVALID) )
00402         {
00403             if( functions->device_removed!=NULL )
00404             {
00405                 functions->device_removed(udi);
00406                 dbus_free(udi);
00407             }
00408         }
00409     }
00410     else if( dbus_message_is_signal(message, "org.freedesktop.Hal.Manager",
00411                                     "NewCapability") )
00412     {
00413         char* udi;
00414         char* capability;
00415         if( dbus_message_get_args(message, &error, 
00416                                   DBUS_TYPE_STRING, &udi,
00417                                   DBUS_TYPE_STRING, &capability,
00418                                   DBUS_TYPE_INVALID) )
00419         {
00420             if( functions->device_new_capability!=NULL )
00421             {
00422                 functions->device_new_capability(udi, capability);
00423                 dbus_free(udi);
00424                 dbus_free(capability);
00425             }
00426         }
00427     }
00428     else if( dbus_message_is_signal(message, "org.freedesktop.Hal.Device",
00429                                     "Condition") )
00430     {
00431         if( functions->device_condition!=NULL )
00432         {
00433             DBusMessageIter iter;
00434             char* condition_name;
00435 
00436             dbus_message_iter_init(message, &iter);
00437             condition_name = dbus_message_iter_get_string(&iter);
00438 
00439             functions->device_condition(object_path, condition_name, message);
00440 
00441             dbus_free(condition_name);
00442         }
00443     }
00444     else if( dbus_message_is_signal(message, "org.freedesktop.Hal.Device",
00445                                     "PropertyModified") )
00446     {
00447         if( functions->device_property_modified!=NULL )
00448         {
00449             int i;
00450             char* key;
00451             dbus_bool_t removed, added;
00452             int num_modifications;
00453             DBusMessageIter iter;
00454 
00455             dbus_message_iter_init(message, &iter);
00456             num_modifications = dbus_message_iter_get_int32(&iter);
00457             dbus_message_iter_next(&iter);
00458 
00459 
00460             for(i=0; i<num_modifications; i++)
00461             {
00462                 
00463                 key = dbus_message_iter_get_string(&iter);
00464                 dbus_message_iter_next(&iter);
00465                 removed = dbus_message_iter_get_boolean(&iter);
00466                 dbus_message_iter_next(&iter);
00467                 added = dbus_message_iter_get_boolean(&iter);
00468                 dbus_message_iter_next(&iter);
00469                 
00470                 functions->device_property_modified(object_path, key,
00471                                                     removed, added);
00472                 
00473                 dbus_free(key);
00474             }
00475 
00476         }
00477     }
00478 
00479     return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
00480 }
00481 
00482 static LibHalFunctions hal_null_functions = {
00483     NULL /*mainloop_integration*/,
00484     NULL /*device_added*/, 
00485     NULL /*device_removed*/, 
00486     NULL /*device_new_capability*/,
00487     NULL /*property_modified*/,
00488     NULL /*device_condition*/
00489 };
00490 
00509 int hal_initialize(const LibHalFunctions* cb_functions, 
00510                    dbus_bool_t use_cache)
00511 {
00512     DBusError error;
00513 
00514     if( is_initialized )
00515     {
00516         fprintf(stderr,"%s %d : Is already initialized!\n",__FILE__, __LINE__);
00517         return 1;
00518     }
00519 
00520     cache_enabled = use_cache;
00521 
00522     functions = cb_functions;
00523     /* allow caller to pass NULL */
00524     if( functions==NULL )
00525         functions = &hal_null_functions;
00526 
00527     // connect to hald service on the system bus
00528     dbus_error_init(&error);
00529     connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
00530     if( connection==NULL )
00531     {
00532         fprintf(stderr, 
00533                 "%s %d : Error connecting to system bus: %s\n",
00534                 __FILE__, __LINE__, error.message);
00535         dbus_error_free(&error);
00536         return 1;
00537     }
00538 
00539     if( functions->main_loop_integration!=NULL )
00540     {
00541 
00542         functions->main_loop_integration(connection);
00543     }
00544 
00545     if( !dbus_connection_add_filter(connection, filter_func, NULL, NULL) )
00546     {
00547         fprintf(stderr, "%s %d : Error creating connection handler\r\n",
00548                 __FILE__, __LINE__);
00549         // TODO: clean up
00550         return 1;
00551     }
00552     
00553     dbus_bus_add_match(connection, 
00554                        "type='signal',"
00555                        "interface='org.freedesktop.Hal.Manager',"
00556                        "sender='org.freedesktop.Hal',"
00557                        "path='/org/freedesktop/Hal/Manager'", &error);
00558     if( dbus_error_is_set(&error) )
00559     {
00560         fprintf(stderr, "%s %d : Error subscribing to signals, "
00561                 "error=%s\r\n",
00562                 __FILE__, __LINE__, error.message);
00563         // TODO: clean up
00564         return 1;
00565     }
00566 
00567     is_initialized = TRUE;
00568     return 0;
00569 }
00570 
00576 int hal_shutdown()
00577 {
00578     if( !is_initialized )
00579         return 1;
00580 
00583     is_initialized = FALSE;
00584     return 0;
00585 }
00586 
00595 char** hal_get_all_devices(int* num_devices)
00596 { 
00597     int i;
00598     DBusError error;
00599     DBusMessage* message;
00600     DBusMessage* reply;
00601     DBusMessageIter iter;
00602     char** device_names;
00603     char** hal_device_names;
00604 
00605     message = dbus_message_new_method_call("org.freedesktop.Hal", 
00606                                            "/org/freedesktop/Hal/Manager",
00607                                            "org.freedesktop.Hal.Manager",
00608                                            "GetAllDevices");
00609     if( message==NULL )
00610     {
00611         fprintf(stderr, "%s %d : Couldn't allocate D-BUS message\n",
00612                 __FILE__, __LINE__);
00613         return NULL;
00614     }
00615     
00616     dbus_error_init(&error);
00617     reply = dbus_connection_send_with_reply_and_block(connection,
00618                                                       message, -1,
00619                                                       &error);
00620     if( dbus_error_is_set(&error) )
00621     {
00622         fprintf(stderr, "%s %d : %s raised\n\"%s\"\n\n", __FILE__, __LINE__,
00623                 error.name, error.message);
00624         dbus_message_unref(message);
00625         return NULL;
00626     }
00627 
00628     if( reply==NULL )
00629     {
00630         dbus_message_unref(message);
00631         return NULL;
00632     }
00633 
00634     // now analyze reply
00635     dbus_message_iter_init(reply, &iter);
00636     if( !dbus_message_iter_get_string_array(&iter, 
00637                                             &device_names, num_devices) )
00638     {
00639         fprintf(stderr, "%s %d : wrong reply from hald\n", __FILE__, __LINE__);
00640         return NULL;
00641     }
00642 
00643     dbus_message_unref(reply);
00644     dbus_message_unref(message);
00645 
00646     /* Have to convert from dbus string array to hal string array 
00647      * since we can't poke at the dbus string array for the reason
00648      * that d-bus use their own memory allocation scheme
00649      */
00650     hal_device_names = malloc(sizeof(char*)*((*num_devices)+1));
00651     if( hal_device_names==NULL )
00652         return NULL; 
00654     for(i=0; i<(*num_devices); i++)
00655     {
00656         hal_device_names[i] = strdup(device_names[i]);
00657         if( hal_device_names[i]==NULL )
00658         {
00659             fprintf(stderr, "%s %d : error allocating memory\n", 
00660                 __FILE__, __LINE__);
00662             return NULL;
00663         }
00664     }
00665     hal_device_names[i] = NULL;
00666 
00667     dbus_free_string_array(device_names);
00668 
00669     return hal_device_names;
00670 }
00671 
00680 int hal_device_get_property_type(const char* udi, 
00681                                  const char* key)
00682 {
00683     DBusError error;
00684     DBusMessage* message;
00685     DBusMessage* reply;
00686     DBusMessageIter iter;
00687     int type;
00688 
00689     message = dbus_message_new_method_call("org.freedesktop.Hal", udi,
00690                                            "org.freedesktop.Hal.Device",
00691                                            "GetPropertyType");
00692     if( message==NULL )
00693     {
00694         fprintf(stderr, "%s %d : Couldn't allocate D-BUS message\n", 
00695                 __FILE__, __LINE__);
00696         return DBUS_TYPE_NIL;
00697     }
00698 
00699     dbus_message_iter_init(message, &iter);
00700     dbus_message_iter_append_string(&iter, key);
00701     dbus_error_init(&error);
00702     reply = dbus_connection_send_with_reply_and_block(connection,
00703                                                       message, -1,
00704                                                       &error);
00705     if( dbus_error_is_set(&error) )
00706     {
00707         fprintf(stderr, "%s %d : %s raised\n\"%s\"\n\n", __FILE__, __LINE__,
00708                 error.name, error.message);
00709         dbus_message_unref(message);
00710         return DBUS_TYPE_NIL;
00711     }
00712     if( reply==NULL )
00713     {
00714         dbus_message_unref(message);
00715         return DBUS_TYPE_NIL;
00716     }
00717 
00718     dbus_message_iter_init(reply, &iter);
00719     type = dbus_message_iter_get_int32(&iter); 
00720    
00721     dbus_message_unref(message);
00722     dbus_message_unref(reply);
00723 
00724     return type;
00725 }
00726 
00737 char* hal_device_get_property_string(const char* udi, const char* key)
00738 {
00739     DBusError error;
00740     DBusMessage* message;
00741     DBusMessage* reply;
00742     DBusMessageIter iter;
00743     char* value;
00744     char* dbus_str;
00745 
00746     message = dbus_message_new_method_call("org.freedesktop.Hal", udi,
00747                                            "org.freedesktop.Hal.Device",
00748                                            "GetPropertyString");
00749     if( message==NULL )
00750     {
00751         fprintf(stderr, "%s %d : Couldn't allocate D-BUS message\n",
00752                 __FILE__, __LINE__);
00753         return NULL;
00754     }
00755 
00756     dbus_message_iter_init(message, &iter);
00757     dbus_message_iter_append_string(&iter, key);
00758     dbus_error_init(&error);
00759     reply = dbus_connection_send_with_reply_and_block(connection,
00760                                                       message, -1,
00761                                                       &error);
00762     if( dbus_error_is_set(&error) )
00763     {
00764         fprintf(stderr, "%s %d : Error sending msg: %s\n", 
00765                 __FILE__, __LINE__, error.message);
00766         dbus_message_unref(message);
00767         return NULL;
00768     }
00769     if( reply==NULL )
00770     {
00771         dbus_message_unref(message);
00772         return NULL;
00773     }
00774 
00775     dbus_message_iter_init(reply, &iter);
00776     
00777     // now analyze reply
00778     if( dbus_message_iter_get_arg_type(&iter)==DBUS_TYPE_NIL )
00779     {
00780         fprintf(stderr, "%s %d : property '%s' for device '%s' does not "
00781                 "exist\n", __FILE__, __LINE__, key, udi);
00782         dbus_message_unref(message);
00783         dbus_message_unref(reply);
00784         return NULL;
00785     }
00786     else if( dbus_message_iter_get_arg_type(&iter)!=DBUS_TYPE_STRING )
00787     {
00788         fprintf(stderr, "%s %d : property '%s' for device '%s' is not "
00789                 "of type string\n", __FILE__, __LINE__, key, udi);
00790         dbus_message_unref(message);
00791         dbus_message_unref(reply);
00792         return NULL;
00793     }
00794 
00795     dbus_str = dbus_message_iter_get_string(&iter);
00796     value = (char*)((dbus_str!=NULL) ? strdup(dbus_str) : NULL);
00797     if( value==NULL )
00798     {
00799         fprintf(stderr, "%s %d : error allocating memory\n", 
00800                 __FILE__, __LINE__);
00802         return NULL;
00803     }
00804     dbus_free(dbus_str);
00805 
00806     dbus_message_unref(message);
00807     dbus_message_unref(reply);
00808     return value;
00809 }
00810 
00817 dbus_int32_t hal_device_get_property_int(const char* udi, const char* key)
00818 {
00819     DBusError error;
00820     DBusMessage* message;
00821     DBusMessage* reply;
00822     DBusMessageIter iter;
00823     dbus_int32_t value;
00824 
00825     message = dbus_message_new_method_call("org.freedesktop.Hal", udi,
00826                                            "org.freedesktop.Hal.Device",
00827                                            "GetPropertyInteger");
00828     if( message==NULL )
00829     {
00830         fprintf(stderr, "%s %d : Couldn't allocate D-BUS message\n",
00831                 __FILE__, __LINE__);
00832         return -1;
00833     }
00834 
00835     dbus_message_iter_init(message, &iter);
00836     dbus_message_iter_append_string(&iter, key);
00837     dbus_error_init(&error);
00838     reply = dbus_connection_send_with_reply_and_block(connection,
00839                                                       message, -1,
00840                                                       &error);
00841     if( dbus_error_is_set(&error) )
00842     {
00843         fprintf(stderr, "%s %d : Error sending msg: %s\n", 
00844                 __FILE__, __LINE__, error.message);
00845         dbus_message_unref(message);
00846         return -1;
00847     }
00848     if( reply==NULL )
00849     {
00850         dbus_message_unref(message);
00851         return -1;
00852     }
00853 
00854     dbus_message_iter_init(reply, &iter);
00855     
00856     // now analyze reply
00857     if( dbus_message_iter_get_arg_type(&iter)==DBUS_TYPE_NIL )
00858     {
00859         // property didn't exist
00860         fprintf(stderr, "%s %d : property '%s' for device '%s' does not "
00861                 "exist\n", __FILE__, __LINE__, key, udi);
00862         dbus_message_unref(message);
00863         dbus_message_unref(reply);
00864         return -1;
00865     }
00866     else if( dbus_message_iter_get_arg_type(&iter)!=DBUS_TYPE_INT32 )
00867     {
00868         fprintf(stderr, "%s %d : property '%s' for device '%s' is not "
00869                 "of type integer\n", __FILE__, __LINE__, key, udi);
00870         dbus_message_unref(message);
00871         dbus_message_unref(reply);
00872         return -1;
00873     }
00874     value = dbus_message_iter_get_int32(&iter);
00875 
00876     dbus_message_unref(message);
00877     dbus_message_unref(reply);
00878     return value;
00879 }
00880 
00887 double hal_device_get_property_double(const char* udi, const char* key)
00888 {
00889     DBusError error;
00890     DBusMessage* message;
00891     DBusMessage* reply;
00892     DBusMessageIter iter;
00893     double value;
00894  
00895     message = dbus_message_new_method_call("org.freedesktop.Hal", udi,
00896                                            "org.freedesktop.Hal.Device",
00897                                            "GetPropertyDouble");
00898     if( message==NULL )
00899     {
00900         fprintf(stderr, "%s %d : Couldn't allocate D-BUS message\n",
00901                 __FILE__, __LINE__);
00902         return -1.0f;
00903     }
00904 
00905     dbus_message_iter_init(message, &iter);
00906     dbus_message_iter_append_string(&iter, key);
00907     dbus_error_init(&error);
00908     reply = dbus_connection_send_with_reply_and_block(connection,
00909                                                       message, -1,
00910                                                       &error);
00911     if( dbus_error_is_set(&error) )
00912     {
00913         fprintf(stderr, "%s %d : Error sending msg: %s\n",
00914                 __FILE__, __LINE__, error.message);
00915         dbus_message_unref(message);
00916         return -1.0f;
00917     }
00918     if( reply==NULL )
00919     {
00920         dbus_message_unref(message);
00921         return -1.0f;
00922     }
00923 
00924     dbus_message_iter_init(reply, &iter);
00925     
00926     // now analyze reply
00927     if( dbus_message_iter_get_arg_type(&iter)==DBUS_TYPE_NIL )
00928     {
00929         // property didn't exist
00930         fprintf(stderr, "%s %d : property '%s' for device '%s' does not "
00931                 "exist\n", __FILE__, __LINE__, key, udi);
00932         dbus_message_unref(message);
00933         dbus_message_unref(reply);
00934         return -1.0f;
00935     }
00936     else if( dbus_message_iter_get_arg_type(&iter)!=DBUS_TYPE_DOUBLE )
00937     {
00938         fprintf(stderr, "%s %d : property '%s' for device '%s' is not "
00939                 "of type double\n", __FILE__, __LINE__, key, udi);
00940         dbus_message_unref(message);
00941         dbus_message_unref(reply);
00942         return -1.0f;
00943     }
00944     value = dbus_message_iter_get_double(&iter);
00945 
00946     dbus_message_unref(message);
00947     dbus_message_unref(reply);
00948     return (double) value;
00949 }
00950 
00957 dbus_bool_t hal_device_get_property_bool(const char* udi, const char* key)
00958 {
00959     DBusError error;
00960     DBusMessage* message;
00961     DBusMessage* reply;
00962     DBusMessageIter iter;
00963     double value;
00964 
00965     message = dbus_message_new_method_call("org.freedesktop.Hal", udi,
00966                                            "org.freedesktop.Hal.Device",
00967                                            "GetPropertyBoolean");
00968     if( message==NULL )
00969     {
00970         fprintf(stderr, "%s %d : Couldn't allocate D-BUS message\n",
00971                 __FILE__, __LINE__);
00972         return FALSE;
00973     }
00974 
00975     dbus_message_iter_init(message, &iter);
00976     dbus_message_iter_append_string(&iter, key);
00977     dbus_error_init(&error);
00978     reply = dbus_connection_send_with_reply_and_block(connection,
00979                                                       message, -1,
00980                                                       &error);
00981     if( dbus_error_is_set(&error) )
00982     {
00983         fprintf(stderr, "%s %d : Error sending msg: %s\n", 
00984                 __FILE__, __LINE__, error.message);
00985         dbus_message_unref(message);
00986         return FALSE;
00987     }
00988     if( reply==NULL )
00989     {
00990         dbus_message_unref(message);
00991         return FALSE;
00992     }
00993 
00994     dbus_message_iter_init(reply, &iter);
00995     
00996     // now analyze reply
00997     if( dbus_message_iter_get_arg_type(&iter)==DBUS_TYPE_NIL )
00998     {
00999         // property didn't exist
01000         fprintf(stderr, "%s %d : property '%s' for device '%s' does not "
01001                 "exist\n", __FILE__, __LINE__, key, udi);
01002         dbus_message_unref(message);
01003         dbus_message_unref(reply);
01004         return FALSE;
01005     }
01006     else if( dbus_message_iter_get_arg_type(&iter)!=DBUS_TYPE_BOOLEAN )
01007     {
01008         fprintf(stderr, "%s %d : property '%s' for device '%s' is not "
01009                 "of type bool\n", __FILE__, __LINE__, key, udi);
01010         dbus_message_unref(message);
01011         dbus_message_unref(reply);
01012         return FALSE;
01013     }
01014     value = dbus_message_iter_get_boolean(&iter);
01015 
01016     dbus_message_unref(message);
01017     dbus_message_unref(reply);
01018     return value;
01019 }
01020 
01021 
01022 // generic helper
01023 static int hal_device_set_property_helper(const char* udi, 
01024                                           const char* key, 
01025                                           int type,
01026                                           const char* str_value,
01027                                           dbus_int32_t int_value,
01028                                           double double_value,
01029                                           dbus_bool_t bool_value)
01030 {
01031     DBusError error;
01032     DBusMessage* message;
01033     DBusMessage* reply;
01034     DBusMessageIter iter;
01035     char* method_name = NULL;
01036 
01037     // TODO: sanity check incoming params
01038 
01039     switch( type )
01040     {
01041     case DBUS_TYPE_NIL:
01042         method_name = "RemoveProperty";
01043         break;
01044     case DBUS_TYPE_STRING:
01045         method_name = "SetPropertyString";
01046         break;
01047     case DBUS_TYPE_INT32:
01048         method_name = "SetPropertyInteger";
01049         break;
01050     case DBUS_TYPE_DOUBLE:
01051         method_name = "SetPropertyDouble";
01052         break;
01053     case DBUS_TYPE_BOOLEAN:
01054         method_name = "SetPropertyBoolean";
01055         break;
01056 
01057     default:
01058         // cannot happen; this is not callable from outside this file..
01059         break;
01060     }
01061 
01062     message = dbus_message_new_method_call("org.freedesktop.Hal", udi,
01063                                            "org.freedesktop.Hal.Device",
01064                                            method_name);
01065     if( message==NULL )
01066     {
01067         fprintf(stderr, "%s %d : Couldn't allocate D-BUS message\n",
01068                 __FILE__, __LINE__);
01069         return FALSE;
01070     }
01071 
01072     dbus_message_iter_init(message, &iter);
01073     dbus_message_iter_append_string(&iter, key);
01074     switch( type )
01075     {
01076     case DBUS_TYPE_NIL:
01077         dbus_message_iter_append_nil(&iter);
01078         break;
01079     case DBUS_TYPE_STRING:
01080         dbus_message_iter_append_string(&iter, str_value);
01081         break;
01082     case DBUS_TYPE_INT32:
01083         dbus_message_iter_append_int32(&iter, int_value);
01084         break;
01085     case DBUS_TYPE_DOUBLE:
01086         dbus_message_iter_append_double(&iter, double_value);
01087         break;
01088     case DBUS_TYPE_BOOLEAN:
01089         dbus_message_iter_append_boolean(&iter, bool_value);
01090         break;
01091     }
01092 
01093     dbus_error_init(&error);
01094     reply = dbus_connection_send_with_reply_and_block(connection,
01095                                                       message, -1,
01096                                                       &error);
01097     if( dbus_error_is_set(&error) )
01098     {
01099         fprintf(stderr, "%s %d: %s raised\n\"%s\"\n\n", __FILE__, __LINE__, 
01100                 error.name, error.message);
01101         dbus_message_unref(message);
01102         return FALSE;
01103     }
01104 
01105     if( reply==NULL )
01106     {
01107         dbus_message_unref(message);
01108         return FALSE;
01109     }
01110 
01111     return TRUE;
01112 }
01113 
01123 dbus_bool_t hal_device_set_property_string(const char* udi, 
01124                                            const char* key, 
01125                                            const char* value)
01126 {
01127     return hal_device_set_property_helper(udi, key, 
01128                                           DBUS_TYPE_STRING, 
01129                                           value, 0, 0.0f, FALSE);
01130 }
01131 
01141 dbus_bool_t hal_device_set_property_int(const char* udi, 
01142                                         const char* key, 
01143                                         dbus_int32_t value)
01144 {
01145     return hal_device_set_property_helper(udi, key, 
01146                                           DBUS_TYPE_INT32,
01147                                           NULL, value, 0.0f, FALSE);
01148 }
01149 
01159 dbus_bool_t hal_device_set_property_double(const char* udi, 
01160                                            const char* key, 
01161                                            double value)
01162 {
01163     return hal_device_set_property_helper(udi, key, 
01164                                           DBUS_TYPE_DOUBLE, 
01165                                           NULL, 0, value, FALSE);
01166 }
01167 
01177 dbus_bool_t hal_device_set_property_bool(const char* udi, 
01178                                          const char* key, 
01179                                          dbus_bool_t value)
01180 {
01181     return hal_device_set_property_helper(udi, key, 
01182                                           DBUS_TYPE_BOOLEAN, 
01183                                           NULL, 0, 0.0f, value);
01184 }
01185 
01186 
01194 dbus_bool_t hal_device_remove_property(const char* udi, const char* key)
01195 {
01196     return hal_device_set_property_helper(udi, key, 
01197                                           DBUS_TYPE_NIL,  //means remove
01198                                           NULL, 0, 0.0f, FALSE);
01199 }
01200 
01201 
01212 char* hal_agent_new_device()
01213 {
01214     DBusError error;
01215     DBusMessage* message;
01216     DBusMessage* reply;
01217     DBusMessageIter iter;
01218     char* value;
01219     char* dbus_str;
01220 
01221     message = dbus_message_new_method_call("org.freedesktop.Hal",
01222                                            "/org/freedesktop/Hal/Manager",
01223                                            "org.freedesktop.Hal.AgentManager",
01224                                            "NewDevice");
01225     if( message==NULL )
01226     {
01227         fprintf(stderr, "%s %d : Couldn't allocate D-BUS message\n",
01228                 __FILE__, __LINE__);
01229         return NULL;
01230     }
01231 
01232     dbus_error_init(&error);
01233     reply = dbus_connection_send_with_reply_and_block(connection,
01234                                                       message, -1,
01235                                                       &error);
01236     if( dbus_error_is_set(&error) )
01237     {
01238         fprintf(stderr, "%s %d : Error sending msg: %s\n", 
01239                 __FILE__, __LINE__, error.message);
01240         dbus_message_unref(message);
01241         return NULL;
01242     }
01243     if( reply==NULL )
01244     {
01245         dbus_message_unref(message);
01246         return NULL;
01247     }
01248 
01249     dbus_message_iter_init(reply, &iter);
01250     
01251     // now analyze reply
01252     if( dbus_message_iter_get_arg_type(&iter)!=DBUS_TYPE_STRING )
01253     {
01254         fprintf(stderr, "%s %d : expected a string in reply to NewDevice\n",
01255                 __FILE__, __LINE__);
01256         dbus_message_unref(message);
01257         dbus_message_unref(reply);
01258         return NULL;
01259     }
01260 
01261     dbus_str = dbus_message_iter_get_string(&iter);
01262     value = (char*)((dbus_str!=NULL) ? strdup(dbus_str) : NULL);
01263     if( value==NULL )
01264     {
01265         fprintf(stderr, "%s %d : error allocating memory\n", 
01266                 __FILE__, __LINE__);
01268         return NULL;
01269     }
01270     dbus_free(dbus_str);
01271 
01272     dbus_message_unref(message);
01273     dbus_message_unref(reply);
01274     return value;
01275 }
01276 
01277 
01295 dbus_bool_t hal_agent_commit_to_gdl(const char* temp_udi, const char* udi)
01296 {
01297     DBusError error;
01298     DBusMessage* message;
01299     DBusMessage* reply;
01300     DBusMessageIter iter;
01301 
01302     message = dbus_message_new_method_call("org.freedesktop.Hal",
01303                                            "/org/freedesktop/Hal/Manager",
01304                                            "org.freedesktop.Hal.AgentManager",
01305                                            "CommitToGdl");
01306     if( message==NULL )
01307     {
01308         fprintf(stderr, "%s %d : Couldn't allocate D-BUS message\n",
01309                 __FILE__, __LINE__);
01310         return FALSE;
01311     }
01312 
01313     dbus_message_iter_init(message, &iter);
01314     dbus_message_iter_append_string(&iter, temp_udi);
01315     dbus_message_iter_append_string(&iter, udi);
01316 
01317     dbus_error_init(&error);
01318     reply = dbus_connection_send_with_reply_and_block(connection,
01319                                                       message, -1,
01320                                                       &error);
01321     if( dbus_error_is_set(&error) )
01322     {
01323         if( dbus_error_has_name(&error, "org.freedesktop.Hal.UdiInUse") )
01324             return FALSE;
01325         fprintf(stderr, "%s %d : Error sending msg: %s\n",
01326                 __FILE__, __LINE__, error.message);
01327         dbus_message_unref(message);
01328         return FALSE;
01329     }
01330     if( reply==NULL )
01331     {
01332         dbus_message_unref(message);
01333         return FALSE;
01334     }
01335 
01336     dbus_message_unref(message);
01337     dbus_message_unref(reply);
01338     return TRUE;
01339 }
01340 
01351 dbus_bool_t hal_agent_remove_device(const char* udi)
01352 {
01353     DBusError error;
01354     DBusMessage* message;
01355     DBusMessage* reply;
01356     DBusMessageIter iter;
01357 
01358     message = dbus_message_new_method_call("org.freedesktop.Hal",
01359                                            "/org/freedesktop/Hal/Manager",
01360                                            "org.freedesktop.Hal.AgentManager",
01361                                            "Remove");
01362     if( message==NULL )
01363     {
01364         fprintf(stderr, "%s %d : Couldn't allocate D-BUS message\n",
01365                 __FILE__, __LINE__);
01366         return FALSE;
01367     }
01368 
01369     dbus_message_iter_init(message, &iter);
01370     dbus_message_iter_append_string(&iter, udi);
01371 
01372     dbus_error_init(&error);
01373     reply = dbus_connection_send_with_reply_and_block(connection,
01374                                                       message, -1,
01375                                                       &error);
01376     if( dbus_error_is_set(&error) )
01377     {
01378         fprintf(stderr, "%s %d : Error sending msg: %s\n",
01379                 __FILE__, __LINE__, error.message);
01380         dbus_message_unref(message);
01381         return FALSE;
01382     }
01383     if( reply==NULL )
01384     {
01385         dbus_message_unref(message);
01386         return FALSE;
01387     }
01388 
01389     dbus_message_unref(message);
01390     dbus_message_unref(reply);
01391     return TRUE;
01392 }
01393 
01399 dbus_bool_t hal_device_exists(const char* udi)
01400 {
01401     DBusError error;
01402     DBusMessage* message;
01403     DBusMessage* reply;
01404     DBusMessageIter iter;
01405     dbus_bool_t value;
01406 
01407     message = dbus_message_new_method_call("org.freedesktop.Hal",
01408                                            "/org/freedesktop/Hal/Manager",
01409                                            "org.freedesktop.Hal.Manager",
01410                                            "DeviceExists");
01411     if( message==NULL )
01412     {
01413         fprintf(stderr, "%s %d : Couldn't allocate D-BUS message\n",
01414                 __FILE__, __LINE__);
01415         return FALSE;
01416     }
01417 
01418     dbus_message_iter_init(message, &iter);
01419     dbus_message_iter_append_string(&iter, udi);
01420 
01421     dbus_error_init(&error);
01422     reply = dbus_connection_send_with_reply_and_block(connection,
01423                                                       message, -1,
01424                                                       &error);
01425     if( dbus_error_is_set(&error) )
01426     {
01427         fprintf(stderr, "%s %d : Error sending msg: %s\n",
01428                 __FILE__, __LINE__, error.message);
01429         dbus_message_unref(message);
01430         return FALSE;
01431     }
01432     if( reply==NULL )
01433     {
01434         dbus_message_unref(message);
01435         return FALSE;
01436     }
01437 
01438     dbus_message_iter_init(reply, &iter);
01439     
01440     // now analyze reply
01441     if( dbus_message_iter_get_arg_type(&iter)!=DBUS_TYPE_BOOLEAN )
01442     {
01443         fprintf(stderr, "%s %d : expected a bool in reply to DeviceExists\n",
01444                 __FILE__, __LINE__);
01445         dbus_message_unref(message);
01446         dbus_message_unref(reply);
01447         return FALSE;
01448     }
01449 
01450     value = dbus_message_iter_get_boolean(&iter);
01451 
01452     dbus_message_unref(message);
01453     dbus_message_unref(reply);
01454     return value;
01455 }
01456 
01463 dbus_bool_t hal_device_property_exists(const char* udi, const char* key)
01464 {
01465     DBusError error;
01466     DBusMessage* message;
01467     DBusMessage* reply;
01468     DBusMessageIter iter;
01469     dbus_bool_t value;
01470 
01471     message = dbus_message_new_method_call("org.freedesktop.Hal", udi,
01472                                            "org.freedesktop.Hal.Device",
01473                                            "PropertyExists");
01474     if( message==NULL )
01475     {
01476         fprintf(stderr, "%s %d : Couldn't allocate D-BUS message\n",
01477                 __FILE__, __LINE__);
01478         return FALSE;
01479     }
01480 
01481     dbus_message_iter_init(message, &iter);
01482     dbus_message_iter_append_string(&iter, key);
01483 
01484     dbus_error_init(&error);
01485     reply = dbus_connection_send_with_reply_and_block(connection,
01486                                                       message, -1,
01487                                                       &error);
01488     if( dbus_error_is_set(&error) )
01489     {
01490         fprintf(stderr, "%s %d : Error sending msg: %s\n",
01491                 __FILE__, __LINE__, error.message);
01492         dbus_message_unref(message);
01493         return FALSE;
01494     }
01495     if( reply==NULL )
01496     {
01497         dbus_message_unref(message);
01498         return FALSE;
01499     }
01500 
01501     dbus_message_iter_init(reply, &iter);
01502     
01503     // now analyze reply
01504     if( dbus_message_iter_get_arg_type(&iter)!=DBUS_TYPE_BOOLEAN )
01505     {
01506         fprintf(stderr, "%s %d : expected a bool in reply to "
01507                 "PropertyExists\n", __FILE__, __LINE__);
01508         dbus_message_unref(message);
01509         dbus_message_unref(reply);
01510         return FALSE;
01511     }
01512 
01513     value = dbus_message_iter_get_boolean(&iter);
01514 
01515     dbus_message_unref(message);
01516     dbus_message_unref(reply);
01517     return value;
01518 }
01519 
01526 dbus_bool_t hal_agent_merge_properties(const char* target_udi, 
01527                                        const char* source_udi)
01528 {
01529     DBusError error;
01530     DBusMessage* message;
01531     DBusMessage* reply;
01532     DBusMessageIter iter;
01533 
01534     message = dbus_message_new_method_call("org.freedesktop.Hal",
01535                                            "/org/freedesktop/Hal/Manager",
01536                                            "org.freedesktop.Hal.AgentManager",
01537                                            "MergeProperties");
01538     if( message==NULL )
01539     {
01540         fprintf(stderr, "%s %d : Couldn't allocate D-BUS message\n",
01541                 __FILE__, __LINE__);
01542         return FALSE;
01543     }
01544 
01545     dbus_message_iter_init(message, &iter);
01546     dbus_message_iter_append_string(&iter, target_udi);
01547     dbus_message_iter_append_string(&iter, source_udi);
01548 
01549     dbus_error_init(&error);
01550     reply = dbus_connection_send_with_reply_and_block(connection,
01551                                                       message, -1,
01552                                                       &error);
01553     if( dbus_error_is_set(&error) )
01554     {
01555         if( dbus_error_has_name(&error, "org.freedesktop.Hal.NoSuchDevice") )
01556             return FALSE;
01557         fprintf(stderr, "%s %d : Error sending msg: %s\n",
01558                 __FILE__, __LINE__, error.message);
01559         dbus_message_unref(message);
01560         return FALSE;
01561     }
01562     if( reply==NULL )
01563     {
01564         dbus_message_unref(message);
01565         return FALSE;
01566     }
01567 
01568     dbus_message_unref(message);
01569     dbus_message_unref(reply);
01570     return TRUE;
01571 }
01572 
01591 dbus_bool_t hal_agent_device_matches(const char* udi1, const char* udi2, 
01592                                      const char* namespace)
01593 {
01594     DBusError error;
01595     DBusMessage* message;
01596     DBusMessage* reply;
01597     DBusMessageIter iter;
01598     dbus_bool_t value;
01599 
01600     message = dbus_message_new_method_call("org.freedesktop.Hal",
01601                                            "/org/freedesktop/Hal/Manager",
01602                                            "org.freedesktop.Hal.AgentManager",
01603                                            "DeviceMatches");
01604     if( message==NULL )
01605     {
01606         fprintf(stderr, "%s %d : Couldn't allocate D-BUS message\n",
01607                 __FILE__, __LINE__);
01608         return FALSE;
01609     }
01610 
01611     dbus_message_iter_init(message, &iter);
01612     dbus_message_iter_append_string(&iter, udi1);
01613     dbus_message_iter_append_string(&iter, udi2);
01614     dbus_message_iter_append_string(&iter, namespace);
01615 
01616     dbus_error_init(&error);
01617     reply = dbus_connection_send_with_reply_and_block(connection,
01618                                                       message, -1,
01619                                                       &error);
01620     if( dbus_error_is_set(&error) )
01621     {
01622         fprintf(stderr, "%s %d : Error sending msg: %s\n", 
01623                 __FILE__, __LINE__, error.message);
01624         dbus_message_unref(message);
01625         return FALSE;
01626     }
01627     if( reply==NULL )
01628     {
01629         dbus_message_unref(message);
01630         return FALSE;
01631     }
01632 
01633     // now analyze reply
01634     dbus_message_iter_init(reply, &iter);
01635     if( dbus_message_iter_get_arg_type(&iter)!=DBUS_TYPE_BOOLEAN )
01636     {
01637         fprintf(stderr,"%s %d : expected a bool in reply to DeviceMatches\n",
01638                 __FILE__, __LINE__);
01639         dbus_message_unref(message);
01640         dbus_message_unref(reply);
01641         return FALSE;
01642     }
01643 
01644     value = dbus_message_iter_get_boolean(&iter);
01645 
01646     dbus_message_unref(message);
01647     dbus_message_unref(reply);
01648     return value;
01649 }
01650 
01655 void hal_device_print(const char* udi)
01656 {
01657     int type;
01658     char* key;
01659     LibHalPropertySet* pset;
01660     LibHalPropertySetIterator i;
01661 
01662     printf("device_id = %s\n", udi);
01663 
01664     pset = hal_device_get_all_properties(udi);
01665 
01666     for(hal_psi_init(&i, pset); hal_psi_has_more(&i); hal_psi_next(&i))
01667     {
01668         type = hal_psi_get_type(&i);
01669         key = hal_psi_get_key(&i);
01670         switch(type)
01671         {
01672         case DBUS_TYPE_STRING:
01673             printf("    %s = %s (string)\n", key, hal_psi_get_string(&i));
01674             break;
01675         case DBUS_TYPE_INT32:
01676             printf("    %s = %d = 0x%x (int)\n", key, hal_psi_get_int(&i),
01677                    hal_psi_get_int(&i));
01678             break;
01679         case DBUS_TYPE_BOOLEAN:
01680             printf("    %s = %s (bool)\n", key, 
01681                    (hal_psi_get_bool(&i) ? "true" : "false"));
01682             break;
01683         case DBUS_TYPE_DOUBLE:
01684             printf("    %s = %g (double)\n", key, hal_psi_get_double(&i));
01685             break;
01686         default:
01687             printf("    *** unknown type for key %s\n", key);
01688             break;
01689         }
01690     }
01691     hal_free_property_set(pset);
01692 }
01693 
01703 char** hal_manager_find_device_string_match(const char* key, 
01704                                             const char* value,
01705                                             int* num_devices)
01706 {
01707     int i;
01708     DBusError error;
01709     DBusMessage* message;
01710     DBusMessage* reply;
01711     DBusMessageIter iter;
01712     char** device_names;
01713     char** hal_device_names;
01714 
01715     message = dbus_message_new_method_call("org.freedesktop.Hal",
01716                                            "/org/freedesktop/Hal/Manager",
01717                                            "org.freedesktop.Hal.Manager",
01718                                            "FindDeviceStringMatch");
01719     if( message==NULL )
01720     {
01721         fprintf(stderr, "%s %d : Couldn't allocate D-BUS message\n",
01722                 __FILE__, __LINE__);
01723         return NULL;
01724     }
01725 
01726     dbus_message_iter_init(message, &iter);
01727     dbus_message_iter_append_string(&iter, key);
01728     dbus_message_iter_append_string(&iter, value);
01729 
01730     dbus_error_init(&error);
01731     reply = dbus_connection_send_with_reply_and_block(connection,
01732                                                       message, -1,
01733                                                       &error);
01734     if( dbus_error_is_set(&error) )
01735     {
01736         fprintf(stderr, "%s %d : Error sending msg: %s\n", 
01737                 __FILE__, __LINE__, error.message);
01738         dbus_message_unref(message);
01739         return NULL;
01740     }
01741     if( reply==NULL )
01742     {
01743         dbus_message_unref(message);
01744         return NULL;
01745     }
01746 
01747     // now analyze reply
01748     dbus_message_iter_init(reply, &iter);
01749     if( !dbus_message_iter_get_string_array(&iter, 
01750                                             &device_names, num_devices) )
01751     {
01752         fprintf(stderr, "%s %d : wrong reply from hald\n", __FILE__, __LINE__);
01753         return NULL;
01754     }
01755 
01756     dbus_message_unref(message);
01757     dbus_message_unref(reply);
01758 
01759     /* Have to convert from dbus string array to hal string array 
01760      * since we can't poke at the dbus string array for the reason
01761      * that d-bus use their own memory allocation scheme
01762      */
01763     hal_device_names = malloc(sizeof(char*)*((*num_devices)+1));
01764     if( hal_device_names==NULL )
01765         return NULL; 
01767     for(i=0; i<(*num_devices); i++)
01768     {
01769         hal_device_names[i] = strdup(device_names[i]);
01770         if( hal_device_names[i]==NULL )
01771             return NULL; 
01772     }
01773     hal_device_names[i] = NULL;
01774 
01775     dbus_free_string_array(device_names);
01776 
01777     return hal_device_names;
01778 }
01779 
01780 
01788 dbus_bool_t hal_device_add_capability(const char* udi, 
01789                                       const char* capability)
01790 {
01791     DBusError error;
01792     DBusMessage* message;
01793     DBusMessage* reply;
01794     DBusMessageIter iter;
01795 
01796     message = dbus_message_new_method_call("org.freedesktop.Hal", udi,
01797                                            "org.freedesktop.Hal.Device",
01798                                            "AddCapability");
01799     if( message==NULL )
01800     {
01801         fprintf(stderr, "%s %d : Couldn't allocate D-BUS message\n",
01802                 __FILE__, __LINE__);
01803         return FALSE;
01804     }
01805 
01806     dbus_message_iter_init(message, &iter);
01807     dbus_message_iter_append_string(&iter, capability);
01808 
01809     dbus_error_init(&error);
01810     reply = dbus_connection_send_with_reply_and_block(connection,
01811                                                       message, -1,
01812                                                       &error);
01813     if( dbus_error_is_set(&error) )
01814     {
01815         fprintf(stderr, "%s %d: %s raised\n\"%s\"\n\n", __FILE__, __LINE__, 
01816                 error.name, error.message);
01817         dbus_message_unref(message);
01818         return FALSE;
01819     }
01820 
01821     if( reply==NULL )
01822     {
01823         dbus_message_unref(message);
01824         return FALSE;
01825     }
01826 
01827     dbus_message_unref(reply);
01828     dbus_message_unref(message);
01829     return TRUE;
01830 }
01831 
01840 dbus_bool_t hal_device_query_capability(const char* udi, 
01841                                         const char* capability)
01842 {
01843     char* caps;
01844 
01845     caps = hal_device_get_property_string(udi, "info.capabilities");
01846 
01847     if( caps!=NULL )
01848         if( strstr(caps, capability)!=NULL )
01849             return TRUE;
01850 
01851     return FALSE;
01852 }
01853 
01861 char** hal_find_device_by_capability(const char* capability, int* num_devices)
01862 {
01863     int i;
01864     DBusError error;
01865     DBusMessage* message;
01866     DBusMessage* reply;
01867     DBusMessageIter iter;
01868     char** device_names;
01869     char** hal_device_names;
01870 
01871     message = dbus_message_new_method_call("org.freedesktop.Hal",
01872                                            "/org/freedesktop/Hal/Manager",
01873                                            "org.freedesktop.Hal.Manager",
01874                                            "FindDeviceByCapability");
01875     if( message==NULL )
01876     {
01877         fprintf(stderr, "%s %d : Couldn't allocate D-BUS message\n",
01878                 __FILE__, __LINE__);
01879         return NULL;
01880     }
01881 
01882     dbus_message_iter_init(message, &iter);
01883     dbus_message_iter_append_string(&iter, capability);
01884 
01885     dbus_error_init(&error);
01886     reply = dbus_connection_send_with_reply_and_block(connection,
01887                                                       message, -1,
01888                                                       &error);
01889     if( dbus_error_is_set(&error) )
01890     {
01891         fprintf(stderr, "%s %d : Error sending msg: %s\n", 
01892                 __FILE__, __LINE__, error.message);
01893         dbus_message_unref(message);
01894         return NULL;
01895     }
01896     if( reply==NULL )
01897     {
01898         dbus_message_unref(message);
01899         return NULL;
01900     }
01901 
01902     // now analyze reply
01903     dbus_message_iter_init(reply, &iter);
01904     if( !dbus_message_iter_get_string_array(&iter, 
01905                                             &device_names, num_devices) )
01906     {
01907         fprintf(stderr, "%s %d : wrong reply from hald\n", __FILE__, __LINE__);
01908         return NULL;
01909     }
01910 
01911     dbus_message_unref(message);
01912     dbus_message_unref(reply);
01913 
01914     /* Have to convert from dbus string array to hal string array 
01915      * since we can't poke at the dbus string array for the reason
01916      * that d-bus use their own memory allocation scheme
01917      */
01918     hal_device_names = malloc(sizeof(char*)*((*num_devices)+1));
01919     if( hal_device_names==NULL )
01920         return NULL; 
01922     for(i=0; i<(*num_devices); i++)
01923     {
01924         hal_device_names[i] = strdup(device_names[i]);
01925         if( hal_device_names[i]==NULL )
01926             return NULL; 
01927     }
01928     hal_device_names[i] = NULL;
01929 
01930     dbus_free_string_array(device_names);
01931 
01932     return hal_device_names;    
01933 }
01934 
01941 int hal_device_property_watch_all()
01942 {
01943     DBusError error;
01944 
01945     dbus_error_init(&error);
01946 
01947     dbus_bus_add_match(connection, 
01948                        "type='signal',"
01949                        "interface='org.freedesktop.Hal.Device',"
01950                        "sender='org.freedesktop.Hal'", &error);
01951     if( dbus_error_is_set(&error) )
01952     {
01953         fprintf(stderr, "%s %d : Error subscribing to signals, "
01954                 "error=%s\r\n",
01955                 __FILE__, __LINE__, error.message);
01956         return 1;
01957     }
01958     return 0;
01959 }
01960 
01961 
01972 int hal_device_add_property_watch(const char* udi)
01973 {
01974     char buf[512];
01975     DBusError error;
01976 
01977     dbus_error_init(&error);
01978 
01979     snprintf(buf, 512, 
01980              "type='signal',"
01981              "interface='org.freedesktop.Hal.Device',"
01982              "sender='org.freedesktop.Hal',"
01983              "path=%s", udi);
01984 
01985     dbus_bus_add_match(connection, buf, &error);
01986     if( dbus_error_is_set(&error) )
01987     {
01988         fprintf(stderr, "%s %d : Error subscribing to signals, "
01989                 "error=%s\r\n",
01990                 __FILE__, __LINE__, error.message);
01991         return 1;
01992     }
01993     return 0;
01994 }
01995 
01996 
02003 int hal_device_remove_property_watch(const char* udi)
02004 {
02005     char buf[512];
02006     DBusError error;
02007 
02008     dbus_error_init(&error);
02009 
02010     snprintf(buf, 512, 
02011              "type='signal',"
02012              "interface='org.freedesktop.Hal.Device',"
02013              "sender='org.freedesktop.Hal',"
02014              "path=%s", udi);
02015 
02016     dbus_bus_remove_match(connection, buf, &error);
02017     if( dbus_error_is_set(&error) )
02018     {
02019         fprintf(stderr, "%s %d : Error unsubscribing to signals, "
02020                 "error=%s\r\n",
02021                 __FILE__, __LINE__, error.message);
02022         return 1;
02023     }
02024     return 0;
02025 }
02026 
02027 

Generated on Sat Feb 7 22:11:46 2004 for HAL by doxygen 1.3.5