e_dbus/connman: remove deprecated properties
[framework/uifw/edbus.git] / src / lib / bluez / e_bluez.c
1 #include "e_bluez_private.h"
2 #include <stdlib.h>
3 #include <string.h>
4
5 static E_DBus_Signal_Handler *cb_name_owner_changed = NULL;
6 static DBusPendingCall *pending_get_name_owner = NULL;
7 static unsigned int init_count = 0;
8 static char *unique_name = NULL;
9
10 static const char bus_name[] = "org.bluez";
11
12 E_DBus_Connection *e_bluez_conn = NULL;
13
14 EAPI int E_BLUEZ_EVENT_MANAGER_IN = 0;
15 EAPI int E_BLUEZ_EVENT_MANAGER_OUT = 0;
16 EAPI int E_BLUEZ_EVENT_ELEMENT_ADD = 0;
17 EAPI int E_BLUEZ_EVENT_ELEMENT_DEL = 0;
18 EAPI int E_BLUEZ_EVENT_ELEMENT_UPDATED = 0;
19 EAPI int E_BLUEZ_EVENT_DEVICE_FOUND = 0;
20
21 const char *e_bluez_iface_manager = NULL;
22 const char *e_bluez_iface_adapter = NULL;
23 const char *e_bluez_iface_device = NULL;
24 const char *e_bluez_prop_address = NULL;
25 const char *e_bluez_prop_name = NULL;
26 const char *e_bluez_prop_alias = NULL;
27 const char *e_bluez_prop_class = NULL;
28 const char *e_bluez_prop_icon = NULL;
29 const char *e_bluez_prop_paired = NULL;
30 const char *e_bluez_prop_trusted = NULL;
31 const char *e_bluez_prop_connected = NULL;
32 const char *e_bluez_prop_uuids = NULL;
33 const char *e_bluez_prop_powered = NULL;
34 const char *e_bluez_prop_discoverable = NULL;
35 const char *e_bluez_prop_pairable = NULL;
36 const char *e_bluez_prop_discoverabletimeout = NULL;
37 const char *e_bluez_prop_pairabletimeout = NULL;
38 const char *e_bluez_prop_discovering = NULL;
39 const char *e_bluez_prop_devices = NULL;
40
41 int _e_dbus_bluez_log_dom = -1;
42
43 const char *
44 e_bluez_system_bus_name_get(void)
45 {
46    return unique_name ? unique_name : bus_name;
47 }
48
49 /***********************************************************************
50 * Manager
51 ***********************************************************************/
52
53 /*
54  * FIXME: Do we really need to call Manager.GetProperties()?
55  */
56
57 /**
58  * Synchronize elements with server.
59  *
60  * This will call Manager.GetProperties() on server, retrieve properties
61  * and some element paths and then request their properties.
62  *
63  * This call will add events E_BLUEZ_EVENT_ELEMENT_ADD and
64  * E_BLUEZ_EVENT_ELEMENT_UPDATED to the main loop.
65  *
66  * This will not remove stale elements.
67  *
68  * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
69  */
70 Eina_Bool
71 e_bluez_manager_sync_elements(void)
72 {
73    E_Bluez_Element *manager;
74
75    if (!unique_name)
76       return EINA_FALSE;
77
78    manager = e_bluez_element_register(manager_path, e_bluez_iface_manager);
79    if (manager)
80       e_bluez_element_properties_sync(manager);
81    else
82       return EINA_FALSE;
83
84    DBG("sync_manager: %s (%s)", unique_name, bus_name);
85
86    return EINA_TRUE;
87 }
88
89 static void
90 _e_bluez_system_name_owner_exit(void)
91 {
92    e_bluez_manager_clear_elements();
93    ecore_event_add(E_BLUEZ_EVENT_MANAGER_OUT, NULL, NULL, NULL);
94
95    free(unique_name);
96    unique_name = NULL;
97 }
98
99 static void
100 _e_bluez_system_name_owner_enter(const char *uid)
101 {
102    DBG("enter bluez at %s (old was %s)", uid, unique_name);
103    if (unique_name && strcmp(unique_name, uid) == 0)
104      {
105         DBG("same unique_name for bluez, ignore.");
106         return;
107      }
108
109    if (unique_name)
110       _e_bluez_system_name_owner_exit();
111
112    unique_name = strdup(uid);
113
114    ecore_event_add(E_BLUEZ_EVENT_MANAGER_IN, NULL, NULL, NULL);
115    e_bluez_manager_sync_elements();
116 }
117
118 static void
119 _e_bluez_system_name_owner_changed(void *data __UNUSED__, DBusMessage *msg)
120 {
121    DBusError err;
122    const char *name, *from, *to;
123
124    dbus_error_init(&err);
125    if (!dbus_message_get_args(msg, &err,
126                               DBUS_TYPE_STRING, &name,
127                               DBUS_TYPE_STRING, &from,
128                               DBUS_TYPE_STRING, &to,
129                               DBUS_TYPE_INVALID))
130      {
131         ERR("could not get NameOwnerChanged arguments: %s: %s",
132             err.name, err.message);
133         dbus_error_free(&err);
134         return;
135      }
136
137    if (strcmp(name, bus_name) != 0)
138       return;
139
140    DBG("NameOwnerChanged from=[%s] to=[%s]", from, to);
141
142    if (from[0] == '\0' && to[0] != '\0')
143      {
144         _e_bluez_system_name_owner_enter(to);
145      }
146    else if (from[0] != '\0' && to[0] == '\0')
147      {
148         DBG("exit bluez at %s", from);
149         if (strcmp(unique_name, from) != 0)
150            DBG("%s was not the known name %s, ignored.", from, unique_name);
151         else
152            _e_bluez_system_name_owner_exit();
153      }
154    else
155      {
156         DBG("unknow change from %s to %s", from, to);
157      }
158 }
159
160 static void
161 _e_bluez_get_name_owner(void *data __UNUSED__, DBusMessage *msg, DBusError *err)
162 {
163    DBusMessageIter itr;
164    int t;
165    const char *uid;
166
167    pending_get_name_owner = NULL;
168
169    if (!_dbus_callback_check_and_init(msg, &itr, err))
170       return;
171
172    t = dbus_message_iter_get_arg_type(&itr);
173    if (!_dbus_iter_type_check(t, DBUS_TYPE_STRING))
174       return;
175
176    dbus_message_iter_get_basic(&itr, &uid);
177    if (!uid)
178      {
179         ERR("no name owner!");
180         return;
181      }
182
183    _e_bluez_system_name_owner_enter(uid);
184    return;
185 }
186
187 /**
188  * Initialize E BlueZ (E_Bluez) system.
189  *
190  * This will connect and watch org.bluez.Manager and Element
191  * events and translate to Ecore main loop events, also provide a
192  * proxy for method invocation on server.
193  *
194  * Interesting events are:
195  *   - E_BLUEZ_EVENT_MANAGER_IN: issued when bluez is avaiable.
196  *   - E_BLUEZ_EVENT_MANAGER_OUT: issued when bluez connection is lost.
197  *   - E_BLUEZ_EVENT_ELEMENT_ADD: element was added.
198  *   - E_BLUEZ_EVENT_ELEMENT_DEL: element was deleted.
199  *   - E_BLUEZ_EVENT_ELEMENT_UPDATED: element was updated (properties
200  *     or state changed).
201  *   - E_BLUEZ_EVENT_DEVICE_FOUND: a device was found, raised after calling
202  *     Adapter.StartDiscorvery()
203  *
204  * Manager IN/OUT events do not provide any event information, just
205  * tells you that system is usable or not. After manager is out, all
206  * elements will be removed, so after this event do not use the system anymore.
207  *
208  * Element events will give you an element object. After DEL event callback
209  * returns, that element will not be valid anymore.
210  */
211 unsigned int
212 e_bluez_system_init(E_DBus_Connection *edbus_conn)
213 {
214    init_count++;
215
216    if (init_count > 1)
217       return init_count;
218
219    _e_dbus_bluez_log_dom = eina_log_domain_register
220          ("e_dbus_bluez", EINA_LOG_DEFAULT_COLOR);
221
222    if(_e_dbus_bluez_log_dom < 0)
223      {
224         EINA_LOG_ERR
225            ("impossible to create a log domain for edbus_bluez module");
226         return -1;
227      }
228
229    if (E_BLUEZ_EVENT_MANAGER_IN == 0)
230       E_BLUEZ_EVENT_MANAGER_IN = ecore_event_type_new();
231
232    if (E_BLUEZ_EVENT_MANAGER_OUT == 0)
233       E_BLUEZ_EVENT_MANAGER_OUT = ecore_event_type_new();
234
235    if (E_BLUEZ_EVENT_ELEMENT_ADD == 0)
236       E_BLUEZ_EVENT_ELEMENT_ADD = ecore_event_type_new();
237
238    if (E_BLUEZ_EVENT_ELEMENT_DEL == 0)
239       E_BLUEZ_EVENT_ELEMENT_DEL = ecore_event_type_new();
240
241    if (E_BLUEZ_EVENT_ELEMENT_UPDATED == 0)
242       E_BLUEZ_EVENT_ELEMENT_UPDATED = ecore_event_type_new();
243
244    if (E_BLUEZ_EVENT_DEVICE_FOUND == 0)
245       E_BLUEZ_EVENT_DEVICE_FOUND = ecore_event_type_new();
246
247    if (!e_bluez_iface_manager)
248       e_bluez_iface_manager = eina_stringshare_add("org.bluez.Manager");
249
250    if (!e_bluez_iface_adapter)
251       e_bluez_iface_adapter = eina_stringshare_add("org.bluez.Adapter");
252
253    if (!e_bluez_iface_device)
254       e_bluez_iface_device = eina_stringshare_add("org.bluez.Device");
255
256    if (!e_bluez_prop_address)
257       e_bluez_prop_address = eina_stringshare_add("Address");
258
259    if (!e_bluez_prop_name)
260       e_bluez_prop_name = eina_stringshare_add("Name");
261
262    if (!e_bluez_prop_alias)
263       e_bluez_prop_alias = eina_stringshare_add("Alias");
264
265    if (!e_bluez_prop_class)
266       e_bluez_prop_class = eina_stringshare_add("Class");
267
268    if (!e_bluez_prop_icon)
269       e_bluez_prop_icon = eina_stringshare_add("Icon");
270
271    if (!e_bluez_prop_paired)
272       e_bluez_prop_paired = eina_stringshare_add("Paired");
273
274    if (!e_bluez_prop_trusted)
275       e_bluez_prop_trusted = eina_stringshare_add("Trusted");
276
277    if (!e_bluez_prop_connected)
278       e_bluez_prop_connected = eina_stringshare_add("Connected");
279
280    if (!e_bluez_prop_uuids)
281       e_bluez_prop_uuids = eina_stringshare_add("UUIDs");
282
283    if (!e_bluez_prop_powered)
284       e_bluez_prop_powered = eina_stringshare_add("Powered");
285
286    if (!e_bluez_prop_discoverable)
287       e_bluez_prop_discoverable = eina_stringshare_add("Discoverable");
288
289    if (!e_bluez_prop_pairable)
290       e_bluez_prop_pairable = eina_stringshare_add("Pairable");
291
292    if (!e_bluez_prop_discoverabletimeout)
293       e_bluez_prop_discoverabletimeout = eina_stringshare_add("DiscoverableTimeout");
294
295    if (!e_bluez_prop_pairabletimeout)
296       e_bluez_prop_pairabletimeout = eina_stringshare_add("PairableTimeout");
297
298    if (!e_bluez_prop_discovering)
299       e_bluez_prop_discovering = eina_stringshare_add("Discovering");
300
301    if (!e_bluez_prop_devices)
302       e_bluez_prop_devices = eina_stringshare_add("Devices");
303
304    e_bluez_conn = edbus_conn;
305    cb_name_owner_changed = e_dbus_signal_handler_add
306          (e_bluez_conn, E_DBUS_FDO_BUS, E_DBUS_FDO_PATH, E_DBUS_FDO_INTERFACE, "NameOwnerChanged",
307          _e_bluez_system_name_owner_changed, NULL);
308
309    if (pending_get_name_owner)
310       dbus_pending_call_cancel(pending_get_name_owner);
311
312    pending_get_name_owner = e_dbus_get_name_owner
313          (e_bluez_conn, bus_name, _e_bluez_get_name_owner, NULL);
314
315    e_bluez_elements_init();
316
317    return init_count;
318 }
319
320 static inline void
321 _stringshare_del(const char **str)
322 {
323    if (!*str)
324       return;
325
326    eina_stringshare_del(*str);
327    *str = NULL;
328 }
329
330 /**
331  * Shutdown bluez system.
332  *
333  * When count drops to 0 resources will be released and no calls should be
334  * made anymore.
335  */
336 unsigned int
337 e_bluez_system_shutdown(void)
338 {
339    if (init_count == 0)
340      {
341         ERR("bluez system already shut down.");
342         return 0;
343      }
344
345    init_count--;
346    if (init_count > 0)
347       return init_count;
348
349    _stringshare_del(&e_bluez_iface_manager);
350    _stringshare_del(&e_bluez_iface_adapter);
351    _stringshare_del(&e_bluez_iface_device);
352    _stringshare_del(&e_bluez_prop_address);
353    _stringshare_del(&e_bluez_prop_name);
354    _stringshare_del(&e_bluez_prop_alias);
355    _stringshare_del(&e_bluez_prop_class);
356    _stringshare_del(&e_bluez_prop_icon);
357    _stringshare_del(&e_bluez_prop_paired);
358    _stringshare_del(&e_bluez_prop_trusted);
359    _stringshare_del(&e_bluez_prop_connected);
360    _stringshare_del(&e_bluez_prop_uuids);
361    _stringshare_del(&e_bluez_prop_powered);
362    _stringshare_del(&e_bluez_prop_discoverable);
363    _stringshare_del(&e_bluez_prop_pairable);
364    _stringshare_del(&e_bluez_prop_discoverabletimeout);
365    _stringshare_del(&e_bluez_prop_pairabletimeout);
366    _stringshare_del(&e_bluez_prop_discovering);
367    _stringshare_del(&e_bluez_prop_devices);
368
369    if (pending_get_name_owner)
370      {
371         dbus_pending_call_cancel(pending_get_name_owner);
372         pending_get_name_owner = NULL;
373      }
374
375    if (cb_name_owner_changed)
376      {
377         e_dbus_signal_handler_del(e_bluez_conn, cb_name_owner_changed);
378         cb_name_owner_changed = NULL;
379      }
380
381    if (unique_name)
382       _e_bluez_system_name_owner_exit();
383
384    e_bluez_elements_shutdown();
385    eina_log_domain_unregister(_e_dbus_bluez_log_dom);
386    e_bluez_conn = NULL;
387
388    return init_count;
389 }
390