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