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