00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifdef HAVE_CONFIG_H
00028 # include <config.h>
00029 #endif
00030
00031 #include <assert.h>
00032 #include <stdio.h>
00033 #include <stdlib.h>
00034 #include <string.h>
00035 #include <dbus/dbus.h>
00036 #include <dbus/dbus-glib.h>
00037
00038 #include "logger.h"
00039 #include "hald.h"
00040 #include "device_store.h"
00041
00054
00055 static void async_find_property_changed(HalDevice* device,
00056 const char* key,
00057 dbus_bool_t in_gdl,
00058 dbus_bool_t removed,
00059 dbus_bool_t added);
00060
00062 #define MAX_CB_FUNCS 32
00063
00065 static HalDevicePropertyChangedCallback property_changed_cb[MAX_CB_FUNCS];
00066
00068 static HalDeviceGDLChangedCallback gdl_changed_cb[MAX_CB_FUNCS];
00069
00071 static HalDeviceNewCapabilityCallback new_capability_cb[MAX_CB_FUNCS];
00072
00074 static int num_property_changed_cb = 0;
00075
00077 static int num_gdl_changed_cb = 0;
00078
00080 static int num_new_capability_cb = 0;
00081
00082
00084 static unsigned int device_list_num = 0;
00085
00087 unsigned int temp_device_counter = 0;
00088
00090 static HalDevice* device_list_head = NULL;
00091
00095 void ds_init()
00096 {
00097 device_list_num = 0;
00098 device_list_head = NULL;
00099 temp_device_counter = 0;
00100
00101 num_gdl_changed_cb = 0;
00102 num_new_capability_cb = 0;
00103 num_property_changed_cb = 1;
00104 property_changed_cb[0] = async_find_property_changed;
00105 }
00106
00111 void ds_add_cb_newcap(HalDeviceNewCapabilityCallback cb)
00112 {
00113 if( num_property_changed_cb < MAX_CB_FUNCS )
00114 new_capability_cb[num_new_capability_cb++] = cb;
00115 }
00116
00121 void ds_add_cb_property_changed(HalDevicePropertyChangedCallback cb)
00122 {
00123 if( num_property_changed_cb < MAX_CB_FUNCS )
00124 property_changed_cb[num_property_changed_cb++] = cb;
00125 }
00126
00131 void ds_add_cb_gdl_changed(HalDeviceGDLChangedCallback cb)
00132 {
00133 if( num_gdl_changed_cb < MAX_CB_FUNCS )
00134 gdl_changed_cb[num_gdl_changed_cb++] = cb;
00135 }
00136
00137
00138
00141 void ds_shutdown()
00142 {
00143 }
00144
00149 void ds_print(HalDevice* device)
00150 {
00151 HalPropertyIterator iter;
00152
00153 printf("device udi = %s (%s)\n", ds_device_get_udi(device),
00154 device->in_gdl ? "in GDL" : "NOT in GDL");
00155
00156 for(ds_property_iter_begin(device, &iter);
00157 ds_property_iter_has_more(&iter);
00158 ds_property_iter_next(&iter))
00159 {
00160 int type;
00161 HalProperty* p;
00162 const char* key;
00163
00164 p = ds_property_iter_get(&iter);
00165
00166 key = ds_property_iter_get_key(p);
00167 type = ds_property_iter_get_type(p);
00168
00169 switch( type )
00170 {
00171 case DBUS_TYPE_STRING:
00172 printf(" %s = '%s' (string)\n", key,
00173 ds_property_iter_get_string(p));
00174 break;
00175
00176 case DBUS_TYPE_INT32:
00177 printf(" %s = %d 0x%x (int)\n", key,
00178 ds_property_iter_get_int(p),
00179 ds_property_iter_get_int(p));
00180 break;
00181
00182 case DBUS_TYPE_DOUBLE:
00183 printf(" %s = %g (double)\n", key,
00184 ds_property_iter_get_double(p));
00185 break;
00186
00187 case DBUS_TYPE_BOOLEAN:
00188 printf(" %s = %s (bool)\n", key,
00189 (ds_property_iter_get_bool(p) ? "true" : "false"));
00190 break;
00191
00192 default:
00193 HAL_WARNING(("Unknown property type %d", type));
00194 break;
00195 }
00196 }
00197 printf("\n");
00198 }
00199
00200
00201
00208 HalDevice* ds_device_find(const char* udi)
00209 {
00210 HalDevice* it;
00211
00212 for(it=device_list_head; it!=NULL; it=it->next)
00213 {
00214 if( strcmp(it->udi, udi)==0 )
00215 return it;
00216 }
00217 return NULL;
00218 }
00219
00221 typedef struct DSDeviceAsyncFindStruct_s
00222 {
00223 char* key;
00224 char* value;
00226 dbus_bool_t only_gdl;
00227 DSAsyncFindDeviceCB callback;
00228 void* data1;
00229 void* data2;
00230 guint timeout_id;
00232 struct DSDeviceAsyncFindStruct_s* next;
00233 } DSDeviceAsyncFindStruct;
00234
00236 static DSDeviceAsyncFindStruct* async_find_outstanding_head = NULL;
00237
00243 static gboolean async_find_timeout_fn(gpointer data)
00244 {
00245 void* data1;
00246 void* data2;
00247 DSAsyncFindDeviceCB callback;
00248 DSDeviceAsyncFindStruct* i;
00249 DSDeviceAsyncFindStruct* prev;
00250 DSDeviceAsyncFindStruct* afs = (DSDeviceAsyncFindStruct*) data;
00251
00252
00253 for(i=async_find_outstanding_head, prev=NULL; i!=NULL; i=i->next)
00254 {
00255 if( i==afs )
00256 {
00257 data1 = i->data1;
00258 data2 = i->data2;
00259 callback = i->callback;
00260
00261
00262 if( prev!=NULL )
00263 {
00264 prev->next = i->next;
00265 }
00266 else
00267 {
00268 async_find_outstanding_head = i->next;
00269 }
00270
00271
00272 free(i->key);
00273 free(i->value);
00274 free(i);
00275
00276
00277
00278
00279
00280 (*callback)(NULL, data1, data2);
00281
00282 return FALSE;
00283 }
00284
00285 prev = i;
00286 }
00287 return FALSE;
00288 }
00289
00290
00299 static void async_find_check_new_addition(HalDevice* device)
00300 {
00301 int type;
00302 void* data1;
00303 void* data2;
00304 DSAsyncFindDeviceCB callback;
00305 DSDeviceAsyncFindStruct* i;
00306 DSDeviceAsyncFindStruct* prev;
00307
00308 check_list_again:
00309
00310
00311 for(i=async_find_outstanding_head, prev=NULL; i!=NULL; i=i->next)
00312 {
00313
00314
00315 type = ds_property_get_type(device, i->key);
00316 if( type==DBUS_TYPE_STRING )
00317 {
00318 if( strcmp(ds_property_get_string(device, i->key), i->value)==0 &&
00319 ( (!(i->only_gdl)) || (i->only_gdl && device->in_gdl)) )
00320 {
00321
00322
00323
00324
00325 data1 = i->data1;
00326 data2 = i->data2;
00327 callback = i->callback;
00328
00329
00330 if( prev!=NULL )
00331 {
00332 prev->next = i->next;
00333 }
00334 else
00335 {
00336 async_find_outstanding_head = i->next;
00337 }
00338
00339
00340 free(i->key);
00341 free(i->value);
00342 free(i);
00343
00344
00345
00346
00347
00348 (*callback)(device, data1, data2);
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363 goto check_list_again;
00364
00365 }
00366 }
00367 prev = i;
00368 }
00369 }
00370
00380 static void async_find_property_changed(HalDevice* device,
00381 const char* key,
00382 dbus_bool_t in_gdl,
00383 dbus_bool_t removed,
00384 dbus_bool_t added)
00385 {
00386 if( !removed )
00387 async_find_check_new_addition(device);
00388 }
00389
00390
00416 void ds_device_async_find_by_key_value_string(const char* key,
00417 const char* value,
00418 dbus_bool_t only_gdl,
00419 DSAsyncFindDeviceCB callback,
00420 void* data1,
00421 void* data2,
00422 int timeout)
00423 {
00424 HalDevice* device;
00425 DSDeviceAsyncFindStruct* afs;
00426
00427 assert( callback!=NULL );
00428
00429
00430 device = ds_device_find_by_key_value_string(key, value, only_gdl);
00431 if( device!=NULL )
00432 {
00433
00434 (*callback)(device, data1, data2 );
00435 return;
00436 }
00437
00438 if( timeout==0 )
00439 {
00440 (*callback)(NULL, data1, data2 );
00441 return;
00442 }
00443
00444
00445 afs = xmalloc(sizeof(DSDeviceAsyncFindStruct));
00446 afs->key = xstrdup(key);
00447 afs->value = xstrdup(value);
00448 afs->only_gdl = only_gdl;
00449 afs->callback = callback;
00450 afs->data1 = data1;
00451 afs->data2 = data2;
00452
00453
00454 afs->timeout_id = g_timeout_add(timeout,
00455 async_find_timeout_fn, (gpointer)afs);
00456
00457 afs->next = async_find_outstanding_head;
00458 async_find_outstanding_head = afs;
00459
00460 }
00461
00474 HalDevice** ds_device_find_multiple_by_key_value_string(const char* key,
00475 const char* value,
00476 dbus_bool_t only_gdl,
00477 int* num_results)
00478 {
00479 int type;
00480 int num_devices;
00481 HalDevice* device;
00482 HalDevice** devices;
00483 HalDeviceIterator iter_device;
00484
00487 devices = xmalloc(sizeof(HalDevice*)*1024);
00488 num_devices = 0;
00489
00490 for(ds_device_iter_begin(&iter_device);
00491 ds_device_iter_has_more(&iter_device);
00492 ds_device_iter_next(&iter_device))
00493 {
00494 device = ds_device_iter_get(&iter_device);
00495
00496 if( only_gdl && !device->in_gdl )
00497 continue;
00498
00499 type = ds_property_get_type(device, key);
00500 if( type==DBUS_TYPE_STRING )
00501 {
00502 if( strcmp(ds_property_get_string(device, key),
00503 value)==0 )
00504 devices[num_devices++] = device;
00505 }
00506 }
00507
00508 if( num_devices==0 )
00509 {
00510 free(devices);
00511 return NULL;
00512 }
00513 else
00514 {
00515 if( num_results!=NULL )
00516 *num_results = num_devices;
00517 return devices;
00518 }
00519 }
00520
00531 HalDevice* ds_device_find_by_key_value_string(const char* key,
00532 const char* value,
00533 dbus_bool_t only_gdl)
00534 {
00535 int type;
00536 HalDevice* device;
00537 HalDeviceIterator iter_device;
00538
00539 for(ds_device_iter_begin(&iter_device);
00540 ds_device_iter_has_more(&iter_device);
00541 ds_device_iter_next(&iter_device))
00542 {
00543 device = ds_device_iter_get(&iter_device);
00544
00545 if( only_gdl && !device->in_gdl )
00546 continue;
00547
00548 type = ds_property_get_type(device, key);
00549 if( type==DBUS_TYPE_STRING )
00550 {
00551 if( strcmp(ds_property_get_string(device, key),
00552 value)==0 )
00553 return device;
00554 }
00555 }
00556
00557 return NULL;
00558 }
00559
00566 HalDevice* ds_device_new()
00567 {
00568 char buf[128];
00569 HalDevice* obj;
00570
00571 snprintf(buf, 128, "/org/freedesktop/Hal/devices/temp/%d",
00572 temp_device_counter++);
00573
00574 obj = (HalDevice*) xmalloc(sizeof(HalDevice));
00575
00576 obj->udi = xstrdup(buf);
00577 obj->in_gdl = FALSE;
00578 obj->num_properties = 0;
00579 obj->prop_head = NULL;
00580
00581 obj->prev = NULL;
00582 obj->next = device_list_head;
00583 if( obj->next!=NULL )
00584 obj->next->prev = obj;
00585
00586 device_list_head = obj;
00587 device_list_num++;
00588
00589 return obj;
00590 }
00591
00597 void ds_device_destroy(HalDevice* device)
00598 {
00599 int i;
00600 HalProperty* prop;
00601 HalProperty* prop_next;
00602
00603 if( device->in_gdl )
00604 {
00605 for(i=0; i<num_gdl_changed_cb; i++)
00606 (*(gdl_changed_cb[i]))(device, FALSE);
00607 }
00608
00609
00610 if( device->next!=NULL )
00611 device->next->prev = device->prev;
00612 if( device->prev!=NULL )
00613 device->prev->next = device->next;
00614 if( device_list_head==device )
00615 device_list_head = device->next;
00616 --device_list_num;
00617
00618
00619 for(prop=device->prop_head; prop!=NULL; prop=prop_next)
00620 {
00621 prop_next = prop->next;
00622 free(prop->key);
00623 if( prop->type==DBUS_TYPE_STRING )
00624 free(prop->str_value);
00625 free(prop);
00626 }
00627 free(device->udi);
00628 free(device);
00629 }
00630
00631
00632
00637 void ds_gdl_add(HalDevice* device)
00638 {
00639 int i;
00640 device->in_gdl = TRUE;
00641
00642 for(i=0; i<num_gdl_changed_cb; i++)
00643 (*(gdl_changed_cb[i]))(device, TRUE);
00644
00645
00646
00647
00648 async_find_check_new_addition(device);
00649 }
00650
00655 unsigned int ds_device_size()
00656 {
00657 return device_list_num;
00658 }
00659
00664 void ds_device_iter_begin(HalDeviceIterator* iterator)
00665 {
00666 iterator->position = 0;
00667 iterator->cursor = device_list_head;
00668 }
00669
00675 dbus_bool_t ds_device_iter_has_more(HalDeviceIterator* iterator)
00676 {
00677 return iterator->position<device_list_num;
00678 }
00679
00686 void ds_device_iter_next(HalDeviceIterator* iterator)
00687 {
00688 iterator->position++;
00689 iterator->cursor = iterator->cursor->next;
00690 }
00691
00697 HalDevice* ds_device_iter_get(HalDeviceIterator* iterator)
00698 {
00699 return iterator->cursor;
00700 }
00701
00702
00703
00709 const char* ds_device_get_udi(HalDevice* device)
00710 {
00711 return device->udi;
00712 }
00713
00721 dbus_bool_t ds_device_set_udi(HalDevice* device, const char* udi)
00722 {
00723 if( ds_device_find(udi)!=NULL )
00724 return FALSE;
00725 free(device->udi);
00726 device->udi = xstrdup(udi);
00727 return TRUE;
00728 }
00729
00730
00731
00732
00738 unsigned int ds_properties_size(HalDevice* device)
00739 {
00740 return device->num_properties;
00741 }
00742
00749 dbus_bool_t ds_property_exists(HalDevice* device, const char* key)
00750 {
00751 return ds_property_find(device, key)!=NULL;
00752 }
00753
00761 HalProperty* ds_property_find(HalDevice* device, const char* key)
00762 {
00763 HalProperty* prop;
00764
00765
00766 for(prop=device->prop_head; prop!=NULL; prop=prop->next)
00767 {
00768 if( strcmp(prop->key, key)==0 )
00769 {
00770 return prop;
00771 }
00772 }
00773
00774 return NULL;
00775 }
00776
00782 void ds_property_iter_begin(HalDevice* device, HalPropertyIterator* iterator)
00783 {
00784 iterator->device = device;
00785 iterator->cursor = device->prop_head;
00786 }
00787
00793 dbus_bool_t ds_property_iter_has_more(HalPropertyIterator* iterator)
00794 {
00795 return iterator->cursor!=NULL;
00796 }
00797
00802 void ds_property_iter_next(HalPropertyIterator* iterator)
00803 {
00804 iterator->cursor = iterator->cursor->next;
00805 }
00806
00812 HalProperty* ds_property_iter_get(HalPropertyIterator* iterator)
00813 {
00814 return iterator->cursor;
00815 }
00816
00825 dbus_bool_t ds_property_set_string(HalDevice* device, const char* key,
00826 const char* value)
00827 {
00828 int i;
00829 HalProperty* prop;
00830
00831
00832 for(prop=device->prop_head; prop!=NULL; prop=prop->next)
00833 {
00834 if( strcmp(prop->key, key)==0 )
00835 {
00836 if( prop->type!=DBUS_TYPE_STRING )
00837 return FALSE;
00838
00839
00840 if( value!=NULL && strcmp(prop->str_value, value)==0 )
00841 {
00842 return TRUE;
00843 }
00844
00845 free(prop->str_value);
00846 prop->str_value = (char*) xstrdup(value);
00847
00848
00849 for(i=0; i<num_property_changed_cb; i++)
00850 (*(property_changed_cb[i]))(device, key, device->in_gdl,
00851 FALSE, FALSE);
00852 return TRUE;
00853 }
00854 }
00855
00856
00857
00858 prop = (HalProperty*) malloc(sizeof(HalProperty));
00859 if( prop==NULL )
00860 return FALSE;
00861 prop->key = (char*) xstrdup(key);
00862 prop->str_value = (char*) xstrdup(value);
00863
00864 prop->type = DBUS_TYPE_STRING;
00865
00866 prop->next = device->prop_head;
00867 prop->prev = NULL;
00868 device->prop_head = prop;
00869 device->num_properties++;
00870 if( prop->next!=NULL )
00871 prop->next->prev = prop;
00872
00873
00874 for(i=0; i<num_property_changed_cb; i++)
00875 (*(property_changed_cb[i]))(device, key, device->in_gdl,
00876 FALSE, TRUE);
00877
00878 return TRUE;
00879 }
00880
00889 dbus_bool_t ds_property_set_int(HalDevice* device, const char* key,
00890 dbus_int32_t value)
00891 {
00892 int i;
00893 HalProperty* prop;
00894
00895
00896 for(prop=device->prop_head; prop!=NULL; prop=prop->next)
00897 {
00898 if( strcmp(prop->key, key)==0 )
00899 {
00900 if( prop->type!=DBUS_TYPE_INT32 )
00901 return FALSE;
00902
00903
00904 if( prop->int_value==value )
00905 return TRUE;
00906
00907 prop->int_value = value;
00908
00909
00910 for(i=0; i<num_property_changed_cb; i++)
00911 (*(property_changed_cb[i]))(device, key, device->in_gdl,
00912 FALSE, FALSE);
00913 return TRUE;
00914 }
00915 }
00916
00917
00918
00919 prop = (HalProperty*) malloc(sizeof(HalProperty));
00920 if( prop==NULL )
00921 return FALSE;
00922 prop->key = (char*) xstrdup(key);
00923 prop->int_value = value;
00924
00925 prop->type = DBUS_TYPE_INT32;
00926
00927 prop->next = device->prop_head;
00928 prop->prev = NULL;
00929 device->prop_head = prop;
00930 device->num_properties++;
00931 if( prop->next!=NULL )
00932 prop->next->prev = prop;
00933
00934
00935 for(i=0; i<num_property_changed_cb; i++)
00936 (*(property_changed_cb[i]))(device, key, device->in_gdl,
00937 FALSE, TRUE);
00938
00939 return TRUE;
00940 }
00941
00950 dbus_bool_t ds_property_set_bool(HalDevice* device, const char* key,
00951 dbus_bool_t value)
00952 {
00953 int i;
00954 HalProperty* prop;
00955
00956
00957 for(prop=device->prop_head; prop!=NULL; prop=prop->next)
00958 {
00959 if( strcmp(prop->key, key)==0 )
00960 {
00961 if( prop->type!=DBUS_TYPE_BOOLEAN )
00962 return FALSE;
00963
00964
00965 if( prop->bool_value==value )
00966 return TRUE;
00967
00968 prop->bool_value = value;
00969
00970
00971 for(i=0; i<num_property_changed_cb; i++)
00972 (*(property_changed_cb[i]))(device, key, device->in_gdl,
00973 FALSE, FALSE);
00974 return TRUE;
00975 }
00976 }
00977
00978
00979
00980 prop = (HalProperty*) malloc(sizeof(HalProperty));
00981 if( prop==NULL )
00982 return FALSE;
00983 prop->key = (char*) xstrdup(key);
00984 prop->bool_value = value;
00985
00986 prop->type = DBUS_TYPE_BOOLEAN;
00987
00988 prop->next = device->prop_head;
00989 prop->prev = NULL;
00990 device->prop_head = prop;
00991 device->num_properties++;
00992 if( prop->next!=NULL )
00993 prop->next->prev = prop;
00994
00995
00996 for(i=0; i<num_property_changed_cb; i++)
00997 (*(property_changed_cb[i]))(device, key, device->in_gdl,
00998 FALSE, TRUE);
00999
01000 return TRUE;
01001 }
01002
01011 dbus_bool_t ds_property_set_double(HalDevice* device, const char* key,
01012 double value)
01013 {
01014 int i;
01015 HalProperty* prop;
01016
01017
01018 for(prop=device->prop_head; prop!=NULL; prop=prop->next)
01019 {
01020 if( strcmp(prop->key, key)==0 )
01021 {
01022 if( prop->type!=DBUS_TYPE_DOUBLE )
01023 return FALSE;
01024
01025
01026 if( prop->double_value==value )
01027 return TRUE;
01028
01029 prop->double_value = value;
01030
01031
01032 for(i=0; i<num_property_changed_cb; i++)
01033 (*(property_changed_cb[i]))(device, key, device->in_gdl,
01034 FALSE, FALSE);
01035 return TRUE;
01036 }
01037 }
01038
01039
01040
01041 prop = (HalProperty*) malloc(sizeof(HalProperty));
01042 if( prop==NULL )
01043 return FALSE;
01044 prop->key = (char*) xstrdup(key);
01045 prop->double_value = value;
01046
01047 prop->type = DBUS_TYPE_DOUBLE;
01048
01049 prop->next = device->prop_head;
01050 prop->prev = NULL;
01051 device->prop_head = prop;
01052 device->num_properties++;
01053 if( prop->next!=NULL )
01054 prop->next->prev = prop;
01055
01056
01057 for(i=0; i<num_property_changed_cb; i++)
01058 (*(property_changed_cb[i]))(device, key, device->in_gdl,
01059 FALSE, TRUE);
01060
01061 return TRUE;
01062 }
01063
01070 dbus_bool_t ds_property_remove(HalDevice* device, const char* key)
01071 {
01072 int i;
01073 int j;
01074 HalProperty* prop;
01075
01076 i=0;
01077
01078 for(prop=device->prop_head; prop!=NULL; prop=prop->next, i++)
01079 {
01080 if( strcmp(prop->key, key)==0 )
01081 {
01082 switch( prop->type )
01083 {
01084 case DBUS_TYPE_STRING:
01085 free( prop->str_value );
01086 break;
01087 case DBUS_TYPE_INT32:
01088 break;
01089 case DBUS_TYPE_DOUBLE:
01090 break;
01091 case DBUS_TYPE_BOOLEAN:
01092 break;
01093 }
01094
01095 free(prop->key);
01096
01097 if( prop->prev==NULL )
01098 {
01099 device->prop_head = prop->next;
01100 if( prop->next!=NULL )
01101 prop->next->prev = NULL;
01102 }
01103 else
01104 {
01105 prop->prev->next = prop->next;
01106 if( prop->next!=NULL )
01107 prop->next->prev = prop->prev;
01108 }
01109 free(prop);
01110 device->num_properties--;
01111
01112 for(j=0; j<num_property_changed_cb; j++)
01113 (*(property_changed_cb[j]))(device, key, device->in_gdl,
01114 TRUE, FALSE);
01115
01116 return TRUE;
01117 }
01118 }
01119
01120 return FALSE;
01121 }
01122
01123
01124
01130 const char* ds_property_iter_get_key(HalProperty* property)
01131 {
01132 return property->key;
01133 }
01134
01141 int ds_property_iter_get_type(HalProperty* property)
01142 {
01143 return property->type;
01144 }
01145
01146
01153 const char* ds_property_iter_get_string(HalProperty* property)
01154 {
01155 if( property->type!=DBUS_TYPE_STRING )
01156 return NULL;
01157 return property->str_value;
01158 }
01159
01165 dbus_int32_t ds_property_iter_get_int(HalProperty* property)
01166 {
01167 return property->int_value;
01168 }
01169
01175 dbus_bool_t ds_property_iter_get_bool(HalProperty* property)
01176 {
01177 return property->bool_value;
01178 }
01179
01185 double ds_property_iter_get_double(HalProperty* property)
01186 {
01187 return property->double_value;
01188 }
01189
01200 void ds_device_merge(HalDevice* target, HalDevice* source)
01201 {
01202 const char* caps;
01203 HalPropertyIterator iter;
01204
01205 property_atomic_update_begin();
01206
01207 for(ds_property_iter_begin(source, &iter);
01208 ds_property_iter_has_more(&iter);
01209 ds_property_iter_next(&iter))
01210 {
01211 int type;
01212 int target_type;
01213 const char* key;
01214 HalProperty* p;
01215
01216 p = ds_property_iter_get(&iter);
01217 key = ds_property_iter_get_key(p);
01218 type = ds_property_iter_get_type(p);
01219
01220
01221 if( strcmp(key, "info.capabilities")==0 )
01222 continue;
01223
01224
01225 target_type = ds_property_get_type(target, key);
01226 if( target_type!=DBUS_TYPE_NIL && target_type!=type )
01227 ds_property_remove(target, key);
01228
01229 switch( type )
01230 {
01231 case DBUS_TYPE_STRING:
01232 ds_property_set_string(target, key,ds_property_iter_get_string(p));
01233 break;
01234 case DBUS_TYPE_INT32:
01235 ds_property_set_int(target, key, ds_property_iter_get_int(p));
01236 break;
01237 case DBUS_TYPE_DOUBLE:
01238 ds_property_set_double(target, key,ds_property_iter_get_double(p));
01239 break;
01240 case DBUS_TYPE_BOOLEAN:
01241 ds_property_set_bool(target, key, ds_property_iter_get_bool(p));
01242 break;
01243 default:
01244 HAL_WARNING(("Unknown property type %d", type));
01245 break;
01246 }
01247 }
01248
01249 property_atomic_update_end();
01250
01251 caps = ds_property_get_string(source, "info.capabilities");
01252 if( caps!=NULL )
01253 {
01254 int i;
01255 char* tok;
01256 char buf[256];
01257 char* bufp = buf;
01258
01259 tok = strtok_r((char*)caps, " ", &bufp);
01260 while( tok!=NULL )
01261 {
01262 if( !ds_query_capability(target, tok) )
01263 {
01264 ds_add_capability(target, tok);
01265 }
01266 tok = strtok_r(NULL, " ", &bufp);
01267 }
01268 }
01269
01270 }
01271
01280 int ds_property_get_type(HalDevice* device, const char* key)
01281 {
01282 HalProperty* prop;
01283
01284
01285 for(prop=device->prop_head; prop!=NULL; prop=prop->next)
01286 {
01287 if( strcmp(prop->key, key)==0 )
01288 {
01289 return prop->type;
01290 }
01291 }
01292 return DBUS_TYPE_NIL;
01293 }
01294
01302 const char* ds_property_get_string(HalDevice* device, const char* key)
01303 {
01304 HalProperty* prop;
01305
01306
01307 for(prop=device->prop_head; prop!=NULL; prop=prop->next)
01308 {
01309 if( strcmp(prop->key, key)==0 )
01310 {
01311 if( prop->type!=DBUS_TYPE_STRING )
01312 return NULL;
01313 return prop->str_value;
01314 }
01315 }
01316 return NULL;
01317 }
01318
01325 dbus_int32_t ds_property_get_int(HalDevice* device, const char* key)
01326 {
01327 HalProperty* prop;
01328
01329
01330 for(prop=device->prop_head; prop!=NULL; prop=prop->next)
01331 {
01332 if( strcmp(prop->key, key)==0 )
01333 {
01334 if( prop->type!=DBUS_TYPE_INT32 )
01335 return -1;
01336 return prop->int_value;
01337 }
01338 }
01339 return -1;
01340 }
01341
01348 dbus_bool_t ds_property_get_bool(HalDevice* device, const char* key)
01349 {
01350 HalProperty* prop;
01351
01352
01353 for(prop=device->prop_head; prop!=NULL; prop=prop->next)
01354 {
01355 if( strcmp(prop->key, key)==0 )
01356 {
01357 if( prop->type!=DBUS_TYPE_BOOLEAN )
01358 return -1;
01359 return prop->bool_value;
01360 }
01361 }
01362 return -1;
01363 }
01364
01371 double ds_property_get_double(HalDevice* device, const char* key)
01372 {
01373 HalProperty* prop;
01374
01375
01376 for(prop=device->prop_head; prop!=NULL; prop=prop->next)
01377 {
01378 if( strcmp(prop->key, key)==0 )
01379 {
01380 if( prop->type!=DBUS_TYPE_DOUBLE )
01381 return -1.0;
01382 return prop->double_value;
01383 }
01384 }
01385 return -1.0;
01386 }
01387
01388
01407 dbus_bool_t ds_device_matches(HalDevice* device1, HalDevice* device2,
01408 const char* namespace)
01409 {
01410 int len;
01411 HalPropertyIterator iter;
01412
01413 len = strlen(namespace);
01414
01415 for(ds_property_iter_begin(device1, &iter);
01416 ds_property_iter_has_more(&iter);
01417 ds_property_iter_next(&iter))
01418 {
01419 int type;
01420 const char* key;
01421 HalProperty* p;
01422
01423 p = ds_property_iter_get(&iter);
01424 key = ds_property_iter_get_key(p);
01425 type = ds_property_iter_get_type(p);
01426
01427 if( strncmp(key, namespace, len)!=0 )
01428 continue;
01429
01430 if( !ds_property_exists(device2, key) )
01431 return FALSE;
01432
01433 switch( type )
01434 {
01435 case DBUS_TYPE_STRING:
01436 if( strcmp(ds_property_iter_get_string(p),
01437 ds_property_get_string(device2, key))!=0 )
01438 return FALSE;
01439 break;
01440 case DBUS_TYPE_INT32:
01441 if( ds_property_iter_get_int(p) !=
01442 ds_property_get_int(device2, key) )
01443 return FALSE;
01444 break;
01445 case DBUS_TYPE_DOUBLE:
01446 if( ds_property_iter_get_double(p) !=
01447 ds_property_get_double(device2, key) )
01448 return FALSE;
01449 break;
01450 case DBUS_TYPE_BOOLEAN:
01451 if( ds_property_iter_get_bool(p) !=
01452 ds_property_get_bool(device2, key) )
01453 return FALSE;
01454 break;
01455 default:
01456 HAL_WARNING(("Unknown property type %d", type));
01457 break;
01458 }
01459 }
01460
01461 return TRUE;
01462 }
01463
01464
01466 #define MAX_CAP_SIZE 2048
01467
01473 void ds_add_capability(HalDevice* device, const char* capability)
01474 {
01475 int i;
01476 const char* caps;
01477 char buf[MAX_CAP_SIZE];
01478
01479 caps = ds_property_get_string(device, "info.capabilities");
01480 if( caps==NULL )
01481 {
01482 ds_property_set_string(device, "info.capabilities", capability);
01483 }
01484 else
01485 {
01486 if( ds_query_capability(device, capability) )
01487 {
01488 return;
01489 }
01490 else
01491 {
01492 snprintf(buf, MAX_CAP_SIZE, "%s %s", caps, capability);
01493 ds_property_set_string(device, "info.capabilities", buf);
01494 }
01495 }
01496
01497 for(i=0; i<num_new_capability_cb; i++)
01498 (*(new_capability_cb[i]))(device, capability, device->in_gdl);
01499 }
01500
01508 dbus_bool_t ds_query_capability(HalDevice* device, const char* capability)
01509 {
01510 const char* caps_orig;
01511 char* caps;
01512 char buf[256];
01513 char* bufp = buf;
01514 char* c;
01515
01516 caps = NULL;
01517 caps_orig = ds_property_get_string(device, "info.capabilities");
01518 if( caps_orig!=NULL )
01519 {
01520
01521 caps = xstrdup(caps_orig);
01522
01523 for(c = strtok_r(caps, " ", &bufp);
01524 c!=NULL;
01525 c = strtok_r(NULL, " ", &bufp))
01526 {
01527 if( strcmp(c, capability)==0 )
01528 {
01529 free(caps);
01530 return TRUE;
01531 }
01532 }
01533
01534 free(caps);
01535 }
01536 return FALSE;
01537 }
01538
01539