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