Migration with svn revision 66792
[framework/uifw/edbus.git] / src / lib / hal / e_hal_device.c
1 #include <stdlib.h>
2
3 #include <E_Hal.h>
4 #include "e_hal_private.h"
5
6 #define e_hal_device_call_new(udi, member) dbus_message_new_method_call(E_HAL_SENDER, udi, E_HAL_DEVICE_INTERFACE, member)
7 #define e_hal_device_volume_call_new(udi, member) dbus_message_new_method_call(E_HAL_SENDER, udi, E_HAL_DEVICE_VOLUME_INTERFACE, member)
8
9 #if 0
10 static void cb_device_get_property(void *data, DBusMessage *msg, DBusError *err);
11 static void cb_device_get_all_properties(void *data, DBusMessage *msg, DBusError *err);
12 static void cb_device_query_capability(void *data, DBusMessage *msg, DBusError *err);
13 #endif
14
15 /* Device.GetProperty */
16 static void *
17 unmarshal_device_get_property(DBusMessage *msg, DBusError *err)
18 {
19   E_Hal_Device_Get_Property_Return *ret = NULL;
20   DBusMessageIter iter;
21   int type;
22   const char *str;
23
24   ret = calloc(1, sizeof(E_Hal_Device_Get_Property_Return));
25   if (!ret) 
26   {
27     dbus_set_error(err, DBUS_ERROR_NO_MEMORY, "");
28     return NULL;
29   }
30
31   dbus_message_iter_init(msg, &iter);
32   type = dbus_message_iter_get_arg_type(&iter);
33   switch(type)
34   {
35     case DBUS_TYPE_STRING:
36       ret->type = E_HAL_PROPERTY_TYPE_STRING;
37       dbus_message_iter_get_basic(&iter, &str);
38       ret->val.s = eina_stringshare_add(str);
39       break;
40     case DBUS_TYPE_INT32:
41       ret->type = E_HAL_PROPERTY_TYPE_INT;
42       dbus_message_iter_get_basic(&iter, &(ret->val.i));
43       break;
44     case DBUS_TYPE_BOOLEAN:
45       ret->type = E_HAL_PROPERTY_TYPE_BOOL;
46       dbus_message_iter_get_basic(&iter, &(ret->val.b));
47       break;
48     case DBUS_TYPE_DOUBLE:
49       ret->type = E_HAL_PROPERTY_TYPE_DOUBLE;
50       dbus_message_iter_get_basic(&iter, &(ret->val.d));
51       break;
52   }
53
54   return ret;
55 }
56
57 static void 
58 free_device_get_property(void *data)
59 {
60   E_Hal_Device_Get_Property_Return *ret = data;
61
62   if (!ret) return;
63   if (ret->type == E_HAL_PROPERTY_TYPE_STRLIST)
64   {
65     const char *str;
66     EINA_LIST_FREE(ret->val.strlist, str)
67       eina_stringshare_del(str);
68   }
69   else if (ret->type == E_HAL_PROPERTY_TYPE_STRING)
70     eina_stringshare_del(ret->val.s);
71   free(ret);
72 }
73
74 EAPI DBusPendingCall *
75 e_hal_device_get_property(E_DBus_Connection *conn, const char *udi, const char *property, E_DBus_Callback_Func cb_func, void *data)
76 {
77   DBusMessage *msg;
78   DBusPendingCall *ret;
79
80   msg = e_hal_device_call_new(udi, "GetProperty");
81   dbus_message_append_args(msg, DBUS_TYPE_STRING, &property, DBUS_TYPE_INVALID);
82   ret = e_dbus_method_call_send(conn, msg, unmarshal_device_get_property, cb_func, free_device_get_property, -1, data);
83   dbus_message_unref(msg);
84   return ret;
85 }
86
87 /* Device.GetAllProperties */
88
89 static void *
90 unmarshal_device_get_all_properties(DBusMessage *msg, DBusError *err)
91 {
92   E_Hal_Device_Get_All_Properties_Return *ret = NULL;
93   DBusMessageIter iter, a_iter, s_iter, v_iter;
94
95   /* a{sv} = array of string+variant */
96   if (!dbus_message_has_signature(msg, "a{sv}")) 
97   {
98     dbus_set_error(err, DBUS_ERROR_INVALID_SIGNATURE, "");
99     return NULL;
100   }
101
102   ret = calloc(1, sizeof(E_Hal_Device_Get_All_Properties_Return));
103   if (!ret) 
104   {
105     dbus_set_error(err, DBUS_ERROR_NO_MEMORY, "");
106     return NULL;
107   }
108
109   ret->properties = eina_hash_string_small_new(EINA_FREE_CB(e_hal_property_free));
110
111   dbus_message_iter_init(msg, &iter);
112   dbus_message_iter_recurse(&iter, &a_iter);
113   while (dbus_message_iter_get_arg_type(&a_iter) != DBUS_TYPE_INVALID)
114   {
115     const char *name;
116     const char *str;
117     E_Hal_Property *prop = calloc(1, sizeof(E_Hal_Property));
118     dbus_message_iter_recurse(&a_iter, &s_iter);
119     dbus_message_iter_get_basic(&s_iter, &name);
120     dbus_message_iter_next(&s_iter);
121     dbus_message_iter_recurse(&s_iter, &v_iter);
122     
123     switch(dbus_message_iter_get_arg_type(&v_iter))
124     {
125       case DBUS_TYPE_STRING:
126         prop->type = E_HAL_PROPERTY_TYPE_STRING;
127         dbus_message_iter_get_basic(&v_iter, &str);
128         prop->val.s = eina_stringshare_add(str);
129         break;
130       case DBUS_TYPE_INT32:
131         prop->type = E_HAL_PROPERTY_TYPE_INT;
132         dbus_message_iter_get_basic(&v_iter, &(prop->val.i));
133         break;
134       case DBUS_TYPE_UINT64:
135         prop->type = E_HAL_PROPERTY_TYPE_UINT64;
136         dbus_message_iter_get_basic(&v_iter, &(prop->val.u64));
137         break;
138       case DBUS_TYPE_BOOLEAN:
139         prop->type = E_HAL_PROPERTY_TYPE_BOOL;
140         dbus_message_iter_get_basic(&v_iter, &(prop->val.b));
141         break;
142       case DBUS_TYPE_DOUBLE:
143         prop->type = E_HAL_PROPERTY_TYPE_DOUBLE;
144         dbus_message_iter_get_basic(&v_iter, &(prop->val.d));
145         break;
146       case DBUS_TYPE_ARRAY:
147         prop->type = E_HAL_PROPERTY_TYPE_STRLIST;
148         {
149           DBusMessageIter list_iter;
150           prop->val.strlist = NULL;
151           dbus_message_iter_recurse(&v_iter, &list_iter);
152           while (dbus_message_iter_get_arg_type(&list_iter) != DBUS_TYPE_INVALID)
153           {
154             dbus_message_iter_get_basic(&list_iter, &str);
155             prop->val.strlist = eina_list_append(prop->val.strlist, eina_stringshare_add(str));
156             dbus_message_iter_next(&list_iter);
157           }
158         }
159         break;
160       default:
161         WARN("Ehal Error: unexpected property type (%s): %c", name, dbus_message_iter_get_arg_type(&v_iter));
162         break;
163     }
164     eina_hash_add(ret->properties, name, prop);
165
166     dbus_message_iter_next(&a_iter);
167   }
168
169   return ret;
170 }
171
172 static void
173 free_device_get_all_properties(void *data)
174 {
175   E_Hal_Device_Get_All_Properties_Return *ret = data;
176
177   if (!ret) return;
178   eina_hash_free(ret->properties);
179   free(ret);
180 }
181
182 EAPI DBusPendingCall *
183 e_hal_device_get_all_properties(E_DBus_Connection *conn, const char *udi, E_DBus_Callback_Func cb_func, void *data)
184 {
185   DBusMessage *msg;
186   DBusPendingCall *ret;
187
188   msg = e_hal_device_call_new(udi, "GetAllProperties");
189   ret = e_dbus_method_call_send(conn, msg, unmarshal_device_get_all_properties, cb_func, free_device_get_all_properties, -1, data);
190   dbus_message_unref(msg);
191   return ret;
192 }
193
194
195
196 /* bool Device.QueryCapability(string udi) */
197
198 // XXX this is same as Device_Exists in manager.
199 static void *
200 unmarshal_device_query_capability(DBusMessage *msg, DBusError *err)
201 {
202   E_Hal_Device_Query_Capability_Return *ret = NULL;
203   dbus_bool_t val;
204
205   ret = calloc(1, sizeof(E_Hal_Manager_Device_Exists_Return));
206   if (!ret) 
207   {
208     dbus_set_error(err, DBUS_ERROR_NO_MEMORY, "");
209     return NULL;
210   }
211
212   dbus_message_get_args(msg, err, DBUS_TYPE_BOOLEAN, &val, DBUS_TYPE_INVALID);
213
214   if (dbus_error_is_set(err))
215   {
216     free(ret);
217     return NULL;
218   }
219
220   ret->boolean = val;
221   return ret;
222 }
223
224 static void
225 free_device_query_capability(void *data)
226 {
227   E_Hal_Device_Query_Capability_Return *ret = data;
228
229   if (!ret) return;
230   free(ret);
231 }
232
233 EAPI DBusPendingCall *
234 e_hal_device_query_capability(E_DBus_Connection *conn, const char *udi, const char *capability, E_DBus_Callback_Func cb_func, void *data)
235 {
236   DBusMessage *msg;
237   DBusPendingCall *ret;
238
239   msg = e_hal_device_call_new(udi, "QueryCapability");
240   dbus_message_append_args(msg, DBUS_TYPE_STRING, &capability, DBUS_TYPE_INVALID);
241   ret = e_dbus_method_call_send(conn, msg, unmarshal_device_query_capability, cb_func, free_device_query_capability, -1, data);
242   dbus_message_unref(msg);
243   return ret;
244 }
245
246
247
248 /* void Device.Mount(string mount_point, string fstype, array{string}options) */
249
250 /**
251  * @brief Mount a Volume
252  *
253  * @param conn the E_DBus_Connection
254  * @param udi the udi of the device object
255  * @param mount_point the path to mount to, or null for default
256  * @param fstype the fstype of the device (e.g. volume.fstype property)
257  * @param options a list of additional options (not sure... fstype dependent?)
258  * @param cb_func an optional callback to call when the mount is done
259  * @param data custom data pointer for the callback function
260  */
261 EAPI DBusPendingCall *
262 e_hal_device_volume_mount(E_DBus_Connection *conn, const char *udi, const char *mount_point, const char *fstype, Eina_List *options, E_DBus_Callback_Func cb_func, void *data)
263 {
264   DBusMessage *msg;
265   DBusMessageIter iter, subiter;
266   Eina_List *l;
267   DBusPendingCall *ret;
268
269   msg = e_hal_device_volume_call_new(udi, "Mount");
270
271   dbus_message_iter_init_append(msg, &iter);
272   dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &mount_point);
273   dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &fstype);
274   if (dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING, &subiter))
275   {
276     if (options)
277     {
278       const char *opt;
279        
280       EINA_LIST_FOREACH(options, l, opt)
281       {
282         dbus_message_iter_append_basic(&subiter, DBUS_TYPE_STRING, &opt);
283       }
284     }
285     dbus_message_iter_close_container(&iter, &subiter);
286   }
287   else
288   {
289     ERR("dbus_message_iter_open_container() failed");
290   }
291
292   ret = e_dbus_method_call_send(conn, msg, NULL, cb_func, NULL, -1, data);
293   dbus_message_unref(msg);
294   return ret;
295 }
296
297 /* void Unmount(array{string} options) */
298
299 /**
300  * @brief Unmount a Volume
301  *
302  * @param conn the E_DBus_Connection
303  * @param udi the udi of the device object
304  * @param options a list of additional options (not sure... fstype dependent?)
305  * @param cb_func an optional callback to call when the unmount is done
306  * @param data cuatom data pointer for the callback function
307  */
308 EAPI DBusPendingCall *
309 e_hal_device_volume_unmount(E_DBus_Connection *conn, const char *udi, Eina_List *options, E_DBus_Callback_Func cb_func, void *data)
310 {
311   DBusMessage *msg;
312   DBusMessageIter iter, subiter;
313   Eina_List *l;
314   DBusPendingCall *ret;
315
316   msg = e_hal_device_volume_call_new(udi, "Unmount");
317
318   dbus_message_iter_init_append(msg, &iter);
319   if (dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING, &subiter))
320   {
321     if (options)
322     {
323       const char *opt;
324        
325       EINA_LIST_FOREACH(options, l, opt)
326       {
327         dbus_message_iter_append_basic(&subiter, DBUS_TYPE_STRING, &opt);
328       }
329     }
330     dbus_message_iter_close_container(&iter, &subiter);
331   }
332   else
333   {
334     ERR("dbus_message_iter_open_container() failed");
335   }
336
337   ret = e_dbus_method_call_send(conn, msg, NULL, cb_func, NULL, -1, data);
338   dbus_message_unref(msg);
339   return ret;
340 }
341
342 /**
343  * @brief Eject a Volume
344  *
345  * @param conn the E_DBus_Connection
346  * @param udi the udi of the device object
347  * @param options a list of additional options (not sure... fstype dependent?)
348  * @param cb_func an optional callback to call when the eject is done
349  * @param data cuatom data pointer for the callback function
350  */
351 EAPI DBusPendingCall *
352 e_hal_device_volume_eject(E_DBus_Connection *conn, const char *udi, Eina_List *options, E_DBus_Callback_Func cb_func, void *data)
353 {
354   DBusMessage *msg;
355   DBusMessageIter iter, subiter;
356   Eina_List *l;
357   DBusPendingCall *ret;
358
359   msg = e_hal_device_volume_call_new(udi, "Eject");
360
361   dbus_message_iter_init_append(msg, &iter);
362   if (dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING, &subiter))
363   {
364     if (options)
365     {
366       const char *opt;
367        
368       EINA_LIST_FOREACH(options, l, opt)
369       {
370         dbus_message_iter_append_basic(&subiter, DBUS_TYPE_STRING, &opt);
371       }
372     }
373     dbus_message_iter_close_container(&iter, &subiter);
374   }
375   else
376   {
377     ERR("dbus_message_iter_open_container() failed");
378   }
379
380   ret = e_dbus_method_call_send(conn, msg, NULL, cb_func, NULL, -1, data);
381   dbus_message_unref(msg);
382   return ret;
383 }