3
* BlueZ - Bluetooth protocol stack for Linux
5
* Copyright (C) 2005-2008 Marcel Holtmann <marcel@holtmann.org>
6
* Copyright (C) 2010 Giovanni Campagna <scampa.giovanni@gmail.com>
7
* Copyright (C) 2013 Intel Corporation.
10
* This library is free software; you can redistribute it and/or
11
* modify it under the terms of the GNU Lesser General Public
12
* License as published by the Free Software Foundation; either
13
* version 2.1 of the License, or (at your option) any later version.
15
* This library is distributed in the hope that it will be useful,
16
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18
* Lesser General Public License for more details.
20
* You should have received a copy of the GNU Lesser General Public
21
* License along with this library; if not, write to the Free Software
22
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27
* SECTION:bluetooth-client
28
* @short_description: Bluetooth client object
30
* @include: bluetooth-client.h
32
* The #BluetoothClient object is used to query the state of Bluetooth
33
* devices and adapters.
41
#include <glib/gi18n-lib.h>
44
#include "bluetooth-client.h"
45
#include "bluetooth-client-private.h"
46
#include "bluetooth-client-glue.h"
47
#include "bluetooth-fdo-glue.h"
48
#include "bluetooth-utils.h"
49
#include "gnome-bluetooth-enum-types.h"
52
#define BLUEZ_SERVICE "org.bluez"
53
#define BLUEZ_MANAGER_PATH "/"
54
#define BLUEZ_ADAPTER_INTERFACE "org.bluez.Adapter1"
55
#define BLUEZ_DEVICE_INTERFACE "org.bluez.Device1"
56
#define FDO_PROPERTIES_INTERFACE "org.freedesktop.DBus.Properties"
58
#define BLUETOOTH_CLIENT_GET_PRIVATE(obj) bluetooth_client_get_instance_private (obj)
60
typedef struct _BluetoothClientPrivate BluetoothClientPrivate;
62
struct _BluetoothClientPrivate {
63
guint owner_change_id;
64
ObjectManager *manager;
66
GtkTreeRowReference *default_adapter;
72
PROP_DEFAULT_ADAPTER_POWERED,
73
PROP_DEFAULT_ADAPTER_DISCOVERABLE,
74
PROP_DEFAULT_ADAPTER_NAME,
75
PROP_DEFAULT_ADAPTER_DISCOVERING
83
static guint signals[LAST_SIGNAL] = { 0 };
85
static const char *connectable_uuids[] = {
89
"A/V_RemoteControlTarget",
93
"HandsfreeAudioGateway",
94
"HumanInterfaceDeviceService",
97
G_DEFINE_TYPE_WITH_PRIVATE(BluetoothClient, bluetooth_client, G_TYPE_OBJECT)
99
typedef gboolean (*IterSearchFunc) (GtkTreeStore *store,
100
GtkTreeIter *iter, gpointer user_data);
102
static gboolean iter_search(GtkTreeStore *store,
103
GtkTreeIter *iter, GtkTreeIter *parent,
104
IterSearchFunc func, gpointer user_data)
106
gboolean cont, found = FALSE;
109
cont = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store),
112
cont = gtk_tree_model_iter_children(GTK_TREE_MODEL(store),
115
while (cont == TRUE) {
118
found = func(store, iter, user_data);
122
found = iter_search(store, &child, iter, func, user_data);
128
cont = gtk_tree_model_iter_next(GTK_TREE_MODEL(store), iter);
134
static gboolean compare_path(GtkTreeStore *store,
135
GtkTreeIter *iter, gpointer user_data)
137
const gchar *path = user_data;
139
gboolean found = FALSE;
141
gtk_tree_model_get(GTK_TREE_MODEL(store), iter,
142
BLUETOOTH_COLUMN_PROXY, &object, -1);
144
if (object != NULL) {
145
found = g_str_equal(path, g_dbus_proxy_get_object_path(object));
146
g_object_unref(object);
153
compare_address (GtkTreeStore *store,
157
const char *address = user_data;
159
gboolean found = FALSE;
161
gtk_tree_model_get (GTK_TREE_MODEL(store), iter,
162
BLUETOOTH_COLUMN_ADDRESS, &tmp_address, -1);
163
found = g_str_equal (address, tmp_address);
164
g_free (tmp_address);
170
get_iter_from_path (GtkTreeStore *store,
174
return iter_search(store, iter, NULL, compare_path, (gpointer) path);
178
get_iter_from_proxy(GtkTreeStore *store,
182
return iter_search(store, iter, NULL, compare_path,
183
(gpointer) g_dbus_proxy_get_object_path (proxy));
187
get_iter_from_address (GtkTreeStore *store,
192
GtkTreeIter parent_iter;
194
if (get_iter_from_proxy (store, &parent_iter, adapter) == FALSE)
197
return iter_search (store, iter, &parent_iter, compare_address, (gpointer) address);
201
device_list_uuids (GVariant *variant)
210
uuids = g_variant_get_strv (variant, NULL);
214
ret = g_ptr_array_new ();
216
for (i = 0; uuids[i] != NULL; i++) {
219
uuid = bluetooth_uuid_to_string (uuids[i]);
222
g_ptr_array_add (ret, g_strdup (uuid));
227
g_ptr_array_free (ret, TRUE);
231
g_ptr_array_add (ret, NULL);
233
return (char **) g_ptr_array_free (ret, FALSE);
237
bluetooth_client_get_connectable(const char **uuids)
241
for (i = 0; uuids && uuids[i] != NULL; i++) {
242
for (j = 0; j < G_N_ELEMENTS (connectable_uuids); j++) {
243
if (g_str_equal (connectable_uuids[j], uuids[i]))
252
phone_oui_to_icon_name (const char *bdaddr)
255
const char *ret = NULL;
257
vendor = oui_to_vendor (bdaddr);
261
if (strstr (vendor, "Apple") != NULL)
262
ret = "phone-apple-iphone";
263
else if (strstr (vendor, "Samsung") != NULL)
264
ret = "phone-samsung-galaxy-s";
265
else if (strstr (vendor, "Google") != NULL)
266
ret = "phone-google-nexus-one";
273
icon_override (const char *bdaddr,
276
/* audio-card, you're ugly */
278
case BLUETOOTH_TYPE_HEADSET:
279
return "audio-headset";
280
case BLUETOOTH_TYPE_HEADPHONES:
281
return "audio-headphones";
282
case BLUETOOTH_TYPE_OTHER_AUDIO:
283
return "audio-speakers";
284
case BLUETOOTH_TYPE_PHONE:
285
return phone_oui_to_icon_name (bdaddr);
286
case BLUETOOTH_TYPE_DISPLAY:
287
return "video-display";
288
case BLUETOOTH_TYPE_SCANNER:
290
case BLUETOOTH_TYPE_REMOTE_CONTROL:
291
case BLUETOOTH_TYPE_WEARABLE:
292
case BLUETOOTH_TYPE_TOY:
300
device_g_properties_changed (GDBusProxy *device,
303
BluetoothClient *client)
305
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
307
const char *property;
311
if (get_iter_from_proxy (priv->store, &iter, device) == FALSE)
314
g_variant_iter_init (&i, changed_p);
315
while (g_variant_iter_next (&i, "{&sv}", &property, &v)) {
317
if (g_str_equal (property, "Name") == TRUE) {
318
const gchar *name = g_variant_get_string (v, NULL);
320
gtk_tree_store_set (priv->store, &iter,
321
BLUETOOTH_COLUMN_NAME, name, -1);
322
} else if (g_str_equal (property, "Alias") == TRUE) {
323
const gchar *alias = g_variant_get_string (v, NULL);
325
gtk_tree_store_set (priv->store, &iter,
326
BLUETOOTH_COLUMN_ALIAS, alias, -1);
327
} else if (g_str_equal (property, "Icon") == TRUE) {
328
const gchar *icon = g_variant_get_string (v, NULL);
330
/* See "Class" handling below */
331
if (g_strcmp0 (icon, "audio-card") != 0) {
332
gtk_tree_store_set (priv->store, &iter,
333
BLUETOOTH_COLUMN_ICON, icon, -1);
335
} else if (g_str_equal (property, "Paired") == TRUE) {
336
gboolean paired = g_variant_get_boolean (v);
338
gtk_tree_store_set (priv->store, &iter,
339
BLUETOOTH_COLUMN_PAIRED, paired, -1);
340
} else if (g_str_equal (property, "Trusted") == TRUE) {
341
gboolean trusted = g_variant_get_boolean (v);
343
gtk_tree_store_set (priv->store, &iter,
344
BLUETOOTH_COLUMN_TRUSTED, trusted, -1);
345
} else if (g_str_equal (property, "Connected") == TRUE) {
346
gboolean connected = g_variant_get_boolean (v);
348
gtk_tree_store_set (priv->store, &iter,
349
BLUETOOTH_COLUMN_CONNECTED, connected, -1);
350
} else if (g_str_equal (property, "UUIDs") == TRUE) {
353
uuids = device_list_uuids (v);
354
gtk_tree_store_set (priv->store, &iter,
355
BLUETOOTH_COLUMN_UUIDS, uuids, -1);
357
} else if (g_str_equal (property, "LegacyPairing") == TRUE) {
358
gboolean legacypairing;
360
legacypairing = g_variant_get_boolean (v);
361
gtk_tree_store_set (priv->store, &iter,
362
BLUETOOTH_COLUMN_LEGACYPAIRING, legacypairing,
364
} else if (g_str_equal (property, "Class") == TRUE) {
366
const char *icon = NULL;
369
gtk_tree_model_get (GTK_TREE_MODEL (priv->store), &iter,
370
BLUETOOTH_COLUMN_ADDRESS, &bdaddr,
373
type = v ? bluetooth_class_to_type (g_variant_get_uint32 (v)) : BLUETOOTH_TYPE_ANY;
374
icon = icon_override (bdaddr, type);
379
gtk_tree_store_set (priv->store, &iter,
380
BLUETOOTH_COLUMN_TYPE, type,
381
BLUETOOTH_COLUMN_ICON, icon,
384
gtk_tree_store_set (priv->store, &iter,
385
BLUETOOTH_COLUMN_TYPE, type,
389
g_debug ("Unhandled property: %s", property);
397
device_added (ObjectManager *manager,
398
BluetoothClient *client,
402
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
405
Properties *properties;
407
const char *adapter_path, *address, *alias, *name, *icon;
409
gboolean paired, trusted, connected;
412
GtkTreeIter iter, parent;
414
device = device1_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
415
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
423
properties = properties_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
424
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
430
dict = g_variant_lookup_value (variant, BLUEZ_DEVICE_INTERFACE,
431
G_VARIANT_TYPE_DICTIONARY);
433
v = g_variant_lookup_value (dict, "Adapter", G_VARIANT_TYPE_OBJECT_PATH);
434
adapter_path = v ? g_variant_get_string (v, NULL) : NULL;
436
v = g_variant_lookup_value (dict, "Address", G_VARIANT_TYPE_STRING);
437
address = v ? g_variant_get_string (v, NULL) : NULL;
439
v = g_variant_lookup_value (dict, "Alias", G_VARIANT_TYPE_STRING);
440
alias = v ? g_variant_get_string (v, NULL) : NULL;
442
v = g_variant_lookup_value (dict, "Name", G_VARIANT_TYPE_STRING);
443
name = v ? g_variant_get_string (v, NULL) : NULL;
445
v = g_variant_lookup_value (dict, "Class", G_VARIANT_TYPE_UINT32);
446
type = v ? bluetooth_class_to_type (g_variant_get_uint32 (v)) : BLUETOOTH_TYPE_ANY;
447
icon = icon_override (address, type);
450
v = g_variant_lookup_value (dict, "Icon", G_VARIANT_TYPE_STRING);
451
icon = v ? g_variant_get_string (v, NULL) : "bluetooth";
454
v = g_variant_lookup_value (dict, "Paired", G_VARIANT_TYPE_BOOLEAN);
455
paired = v ? g_variant_get_boolean (v) : FALSE;
457
v = g_variant_lookup_value (dict, "Trusted", G_VARIANT_TYPE_BOOLEAN);
458
trusted = v ? g_variant_get_boolean (v) : FALSE;
460
v = g_variant_lookup_value (dict, "Connected", G_VARIANT_TYPE_BOOLEAN);
461
connected = v ? g_variant_get_boolean (v) : FALSE;
463
v = g_variant_lookup_value (dict, "UUIDs", G_VARIANT_TYPE_STRING_ARRAY);
464
uuids = device_list_uuids (v);
466
v = g_variant_lookup_value (dict, "LegacyPairing", G_VARIANT_TYPE_BOOLEAN);
467
legacypairing = v ? g_variant_get_boolean (v) : -1;
469
if (get_iter_from_path (priv->store, &parent, adapter_path) == FALSE) {
470
g_object_unref (device);
474
gtk_tree_model_get (GTK_TREE_MODEL(priv->store), &parent,
475
BLUETOOTH_COLUMN_PROXY, &adapter, -1);
477
if (get_iter_from_address (priv->store, &iter, address, adapter) == FALSE) {
478
gtk_tree_store_insert_with_values (priv->store, &iter, &parent, -1,
479
BLUETOOTH_COLUMN_ADDRESS, address,
480
BLUETOOTH_COLUMN_ALIAS, alias,
481
BLUETOOTH_COLUMN_NAME, name,
482
BLUETOOTH_COLUMN_TYPE, type,
483
BLUETOOTH_COLUMN_ICON, icon,
484
BLUETOOTH_COLUMN_LEGACYPAIRING, legacypairing,
485
BLUETOOTH_COLUMN_UUIDS, uuids,
486
BLUETOOTH_COLUMN_PAIRED, paired,
487
BLUETOOTH_COLUMN_CONNECTED, connected,
488
BLUETOOTH_COLUMN_TRUSTED, trusted,
489
BLUETOOTH_COLUMN_PROXY, device,
490
BLUETOOTH_COLUMN_PROPERTIES, properties,
493
gtk_tree_store_set(priv->store, &iter,
494
BLUETOOTH_COLUMN_ADDRESS, address,
495
BLUETOOTH_COLUMN_ALIAS, alias,
496
BLUETOOTH_COLUMN_NAME, name,
497
BLUETOOTH_COLUMN_TYPE, type,
498
BLUETOOTH_COLUMN_ICON, icon,
499
BLUETOOTH_COLUMN_LEGACYPAIRING, legacypairing,
500
BLUETOOTH_COLUMN_UUIDS, uuids,
501
BLUETOOTH_COLUMN_PAIRED, paired,
502
BLUETOOTH_COLUMN_CONNECTED, connected,
503
BLUETOOTH_COLUMN_TRUSTED, trusted,
504
BLUETOOTH_COLUMN_PROXY, device,
505
BLUETOOTH_COLUMN_PROPERTIES, properties,
510
g_signal_connect (G_OBJECT (device), "g-properties-changed",
511
G_CALLBACK (device_g_properties_changed), client);
513
g_object_unref (properties);
514
g_object_unref (device);
515
g_object_unref (adapter);
519
device_removed (const char *path,
520
BluetoothClient *client)
522
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
525
if (get_iter_from_path(priv->store, &iter, path) == TRUE) {
526
g_signal_emit (G_OBJECT (client), signals[DEVICE_REMOVED], 0, path);
527
gtk_tree_store_remove(priv->store, &iter);
532
powered_callback (GDBusProxy *proxy,
536
GError *error = NULL;
538
if (!properties_call_set_finish (PROPERTIES(proxy), res, &error)) {
539
g_debug ("Call to Set Powered failed %s: %s",
540
g_dbus_proxy_get_object_path (proxy), error->message);
541
g_error_free (error);
544
g_object_unref (proxy);
548
adapter_set_powered (BluetoothClient *client,
552
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
553
Properties *properties;
556
g_return_val_if_fail (BLUETOOTH_IS_CLIENT (client), FALSE);
558
if (get_iter_from_path (priv->store, &iter, path) == FALSE)
561
gtk_tree_model_get (GTK_TREE_MODEL (priv->store), &iter,
562
BLUETOOTH_COLUMN_PROPERTIES, &properties, -1);
564
if (properties == NULL)
568
properties_call_set (properties,
569
BLUEZ_ADAPTER_INTERFACE,
571
g_variant_new_variant (g_variant_new_boolean (powered)),
573
(GAsyncReadyCallback) powered_callback,
580
default_adapter_changed (ObjectManager *manager,
582
BluetoothClient *client)
584
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
586
GtkTreePath *tree_path;
589
g_assert (!priv->default_adapter);
591
if (get_iter_from_path (priv->store, &iter, path) == FALSE)
594
tree_path = gtk_tree_model_get_path (GTK_TREE_MODEL (priv->store), &iter);
595
priv->default_adapter = gtk_tree_row_reference_new (GTK_TREE_MODEL (priv->store), tree_path);
596
gtk_tree_path_free (tree_path);
598
gtk_tree_store_set (priv->store, &iter,
599
BLUETOOTH_COLUMN_DEFAULT, TRUE, -1);
601
gtk_tree_model_get (GTK_TREE_MODEL(priv->store), &iter,
602
BLUETOOTH_COLUMN_POWERED, &powered, -1);
605
g_object_notify (G_OBJECT (client), "default-adapter");
606
g_object_notify (G_OBJECT (client), "default-adapter-powered");
607
g_object_notify (G_OBJECT (client), "default-adapter-discoverable");
608
g_object_notify (G_OBJECT (client), "default-adapter-discovering");
609
g_object_notify (G_OBJECT (client), "default-adapter-name");
614
* If the adapter is turn off (Powered = False in bluetooth) object
615
* notifications will be sent only when a Powered = True signal arrives
618
adapter_set_powered (client, path, TRUE);
622
adapter_g_properties_changed (GDBusProxy *adapter,
625
BluetoothClient *client)
627
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
629
const char *property;
632
gboolean notify = FALSE;
634
if (get_iter_from_proxy (priv->store, &iter, adapter) == FALSE)
637
g_variant_iter_init (&i, changed_p);
638
while (g_variant_iter_next (&i, "{&sv}", &property, &v)) {
639
if (g_str_equal (property, "Name") == TRUE) {
640
const gchar *name = g_variant_get_string (v, NULL);
643
gtk_tree_store_set (priv->store, &iter,
644
BLUETOOTH_COLUMN_NAME, name, -1);
645
gtk_tree_model_get (GTK_TREE_MODEL(priv->store), &iter,
646
BLUETOOTH_COLUMN_DEFAULT, &is_default, -1);
647
if (is_default != FALSE) {
648
g_object_notify (G_OBJECT (client), "default-adapter-powered");
649
g_object_notify (G_OBJECT (client), "default-adapter-name");
652
} else if (g_str_equal (property, "Discovering") == TRUE) {
653
gboolean discovering = g_variant_get_boolean (v);
656
gtk_tree_store_set (priv->store, &iter,
657
BLUETOOTH_COLUMN_DISCOVERING, discovering, -1);
658
gtk_tree_model_get (GTK_TREE_MODEL(priv->store), &iter,
659
BLUETOOTH_COLUMN_DEFAULT, &is_default, -1);
660
if (is_default != FALSE)
661
g_object_notify (G_OBJECT (client), "default-adapter-discovering");
663
} else if (g_str_equal (property, "Powered") == TRUE) {
664
gboolean powered = g_variant_get_boolean (v);
667
gtk_tree_store_set (priv->store, &iter,
668
BLUETOOTH_COLUMN_POWERED, powered, -1);
669
gtk_tree_model_get (GTK_TREE_MODEL(priv->store), &iter,
670
BLUETOOTH_COLUMN_DEFAULT, &is_default, -1);
671
if (is_default != FALSE && powered) {
672
g_object_notify (G_OBJECT (client), "default-adapter");
673
g_object_notify (G_OBJECT (client), "default-adapter-powered");
674
g_object_notify (G_OBJECT (client), "default-adapter-discoverable");
675
g_object_notify (G_OBJECT (client), "default-adapter-discovering");
676
g_object_notify (G_OBJECT (client), "default-adapter-name");
679
} else if (g_str_equal (property, "Discoverable") == TRUE) {
680
gboolean discoverable = g_variant_get_boolean (v);
683
gtk_tree_store_set (priv->store, &iter,
684
BLUETOOTH_COLUMN_DISCOVERABLE, discoverable, -1);
685
gtk_tree_model_get (GTK_TREE_MODEL(priv->store), &iter,
686
BLUETOOTH_COLUMN_DEFAULT, &is_default, -1);
687
if (is_default != FALSE)
688
g_object_notify (G_OBJECT (client), "default-adapter-discoverable");
692
if (notify != FALSE) {
696
path = gtk_tree_model_get_path (GTK_TREE_MODEL (priv->store), &iter);
697
gtk_tree_model_row_changed (GTK_TREE_MODEL (priv->store), path, &iter);
698
gtk_tree_path_free (path);
705
adapter_added (ObjectManager *manager,
708
BluetoothClient *client)
710
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
713
Properties *properties;
714
const gchar *address, *name;
716
gboolean discovering, discoverable, powered;
718
adapter = adapter1_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
719
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
725
properties = properties_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
726
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
732
dict = g_variant_lookup_value (variant, BLUEZ_ADAPTER_INTERFACE,
733
G_VARIANT_TYPE_DICTIONARY);
735
v = g_variant_lookup_value (dict, "Address", G_VARIANT_TYPE_STRING);
736
address = v ? g_variant_get_string (v, NULL) : NULL;
738
v = g_variant_lookup_value (dict, "Name", G_VARIANT_TYPE_STRING);
739
name = v ? g_variant_get_string (v, NULL) : NULL;
741
v = g_variant_lookup_value (dict, "Discovering", G_VARIANT_TYPE_BOOLEAN);
742
discovering = v ? g_variant_get_boolean (v) : FALSE;
744
v = g_variant_lookup_value (dict, "Powered", G_VARIANT_TYPE_BOOLEAN);
745
powered = v ? g_variant_get_boolean (v) : FALSE;
747
v = g_variant_lookup_value (dict, "Discoverable", G_VARIANT_TYPE_BOOLEAN);
748
discoverable = v ? g_variant_get_boolean (v) : FALSE;
750
gtk_tree_store_insert_with_values(priv->store, &iter, NULL, -1,
751
BLUETOOTH_COLUMN_PROXY, adapter,
752
BLUETOOTH_COLUMN_PROPERTIES, properties,
753
BLUETOOTH_COLUMN_ADDRESS, address,
754
BLUETOOTH_COLUMN_NAME, name,
755
BLUETOOTH_COLUMN_DISCOVERING, discovering,
756
BLUETOOTH_COLUMN_DISCOVERABLE, discoverable,
757
BLUETOOTH_COLUMN_POWERED, powered,
760
g_signal_connect (G_OBJECT (adapter), "g-properties-changed",
761
G_CALLBACK (adapter_g_properties_changed), client);
763
if (!priv->default_adapter)
764
default_adapter_changed (manager, path, client);
766
g_object_unref (properties);
767
g_object_unref (adapter);
771
adapter_removed (ObjectManager *manager,
773
BluetoothClient *client)
775
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
777
gboolean was_default;
779
if (get_iter_from_path (priv->store, &iter, path) == FALSE)
782
gtk_tree_model_get (GTK_TREE_MODEL(priv->store), &iter,
783
BLUETOOTH_COLUMN_DEFAULT, &was_default, -1);
788
g_clear_pointer (&priv->default_adapter, gtk_tree_row_reference_free);
789
gtk_tree_store_remove (priv->store, &iter);
791
if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL(priv->store),
794
const char *adapter_path;
796
gtk_tree_model_get (GTK_TREE_MODEL(priv->store), &iter,
797
BLUETOOTH_COLUMN_PROXY, &adapter, -1);
799
adapter_path = g_dbus_proxy_get_object_path (adapter);
800
default_adapter_changed (manager, adapter_path, client);
802
g_object_unref(adapter);
804
g_object_notify (G_OBJECT (client), "default-adapter");
805
g_object_notify (G_OBJECT (client), "default-adapter-powered");
806
g_object_notify (G_OBJECT (client), "default-adapter-discoverable");
807
g_object_notify (G_OBJECT (client), "default-adapter-discovering");
812
interface_added (BluetoothClient *client,
816
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
818
if (g_variant_lookup_value (variant, BLUEZ_ADAPTER_INTERFACE,
819
G_VARIANT_TYPE_DICTIONARY)) {
820
g_debug ("New Adapter interface added.");
821
adapter_added (priv->manager, path, variant, client);
825
if (g_variant_lookup_value (variant, BLUEZ_DEVICE_INTERFACE,
826
G_VARIANT_TYPE_DICTIONARY)) {
827
g_debug ("New Device interface added.");
828
device_added (priv->manager, client, path, variant);
834
interface_removed (BluetoothClient *client,
838
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
842
ifaces = g_variant_get_strv (variant, NULL);
844
for (i = 0 ; ifaces[i] != NULL ; i++) {
845
if (g_strcmp0(ifaces[i], BLUEZ_ADAPTER_INTERFACE) == 0) {
846
adapter_removed(priv->manager, path, client);
850
if (g_strcmp0(ifaces[i], BLUEZ_DEVICE_INTERFACE) == 0) {
851
device_removed (path, client);
858
object_manager_g_signal (GDBusProxy *proxy,
861
GVariant *parameters,
862
BluetoothClient *client)
867
g_variant_get (parameters, "(o*)", &object_path, &variant);
869
if (g_strcmp0 (signal_name, "InterfacesAdded") == 0) {
870
interface_added (client, object_path, variant);
871
} else if (g_strcmp0 (signal_name, "InterfacesRemoved") == 0) {
872
interface_removed (client, object_path, variant);
874
g_assert_not_reached ();
877
g_free (object_path);
881
bluez_appeared_cb (GDBusConnection *connection,
883
const gchar *name_owner,
884
BluetoothClient *client)
886
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
888
GVariant *variant, *v, *ifaces;
891
priv->manager = object_manager_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
892
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
898
g_signal_connect (G_OBJECT (priv->manager), "g-signal",
899
G_CALLBACK (object_manager_g_signal), client);
902
object_manager_call_get_managed_objects_sync (OBJECT_MANAGER (priv->manager),
903
&variant, NULL, NULL);
907
g_variant_iter_init (&iter, variant);
908
while ((v = g_variant_iter_next_value (&iter))) {
909
g_variant_get (v, "{o*}", &key, &ifaces);
910
interface_added (client, key, ifaces);
914
g_variant_unref (variant);
918
bluez_vanished_cb (GDBusConnection *connection,
920
BluetoothClient *client)
922
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
924
g_clear_pointer (&priv->default_adapter, gtk_tree_row_reference_free);
926
gtk_tree_store_clear (priv->store);
928
g_clear_object (&priv->manager);
931
static void bluetooth_client_init(BluetoothClient *client)
933
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
935
priv->store = gtk_tree_store_new(_BLUETOOTH_NUM_COLUMNS, G_TYPE_OBJECT,
936
G_TYPE_OBJECT, G_TYPE_STRING,
937
G_TYPE_STRING, G_TYPE_STRING,
938
G_TYPE_UINT, G_TYPE_STRING,
939
G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
940
G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_INT,
941
G_TYPE_BOOLEAN, G_TYPE_HASH_TABLE, G_TYPE_STRV);
943
priv->owner_change_id = g_bus_watch_name (G_BUS_TYPE_SYSTEM,
945
G_BUS_NAME_WATCHER_FLAGS_NONE,
946
(GBusNameAppearedCallback) bluez_appeared_cb,
947
(GBusNameVanishedCallback) bluez_vanished_cb,
952
_bluetooth_client_get_default_adapter(BluetoothClient *client)
954
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
959
g_return_val_if_fail (BLUETOOTH_IS_CLIENT (client), NULL);
961
if (priv->default_adapter == NULL)
964
path = gtk_tree_row_reference_get_path (priv->default_adapter);
965
gtk_tree_model_get_iter (GTK_TREE_MODEL (priv->store), &iter, path);
966
gtk_tree_model_get (GTK_TREE_MODEL (priv->store), &iter,
967
BLUETOOTH_COLUMN_PROXY, &adapter, -1);
968
gtk_tree_path_free (path);
974
_bluetooth_client_get_default_adapter_path (BluetoothClient *self)
976
GDBusProxy *adapter = _bluetooth_client_get_default_adapter (self);
978
if (adapter != NULL) {
979
const char *ret = g_dbus_proxy_get_object_path (adapter);
980
g_object_unref (adapter);
987
_bluetooth_client_get_default_adapter_powered (BluetoothClient *self)
989
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE (self);
994
if (priv->default_adapter == NULL)
997
path = gtk_tree_row_reference_get_path (priv->default_adapter);
998
gtk_tree_model_get_iter (GTK_TREE_MODEL (priv->store), &iter, path);
999
gtk_tree_model_get (GTK_TREE_MODEL (priv->store), &iter, BLUETOOTH_COLUMN_POWERED, &ret, -1);
1000
gtk_tree_path_free (path);
1006
_bluetooth_client_get_default_adapter_name (BluetoothClient *self)
1008
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE (self);
1013
if (priv->default_adapter == NULL)
1016
path = gtk_tree_row_reference_get_path (priv->default_adapter);
1017
gtk_tree_model_get_iter (GTK_TREE_MODEL (priv->store), &iter, path);
1018
gtk_tree_model_get (GTK_TREE_MODEL (priv->store), &iter, BLUETOOTH_COLUMN_NAME, &ret, -1);
1019
gtk_tree_path_free (path);
1025
* _bluetooth_client_get_discoverable:
1026
* @client: a #BluetoothClient
1028
* Gets the default adapter's discoverable status, cached in the adapter model.
1030
* Returns: the discoverable status, or FALSE if no default adapter exists
1033
_bluetooth_client_get_discoverable (BluetoothClient *client)
1035
BluetoothClientPrivate *priv;
1040
g_return_val_if_fail (BLUETOOTH_IS_CLIENT (client), FALSE);
1042
priv = BLUETOOTH_CLIENT_GET_PRIVATE (client);
1043
if (priv->default_adapter == NULL)
1046
path = gtk_tree_row_reference_get_path (priv->default_adapter);
1047
gtk_tree_model_get_iter (GTK_TREE_MODEL (priv->store), &iter, path);
1048
gtk_tree_model_get (GTK_TREE_MODEL (priv->store), &iter,
1049
BLUETOOTH_COLUMN_DISCOVERABLE, &ret, -1);
1055
* _bluetooth_client_set_discoverable:
1056
* @client: a #BluetoothClient object
1057
* @discoverable: whether the device should be discoverable
1058
* @timeout: timeout in seconds for making undiscoverable, or 0 for never
1060
* Sets the default adapter's discoverable status.
1062
* Return value: Whether setting the state on the default adapter was successful.
1065
_bluetooth_client_set_discoverable (BluetoothClient *client,
1066
gboolean discoverable,
1069
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE (client);
1070
GError *error = NULL;
1072
Properties *properties;
1076
g_return_val_if_fail (BLUETOOTH_IS_CLIENT (client), FALSE);
1078
if (priv->default_adapter == NULL)
1081
path = gtk_tree_row_reference_get_path (priv->default_adapter);
1082
gtk_tree_model_get_iter (GTK_TREE_MODEL (priv->store), &iter, path);
1083
gtk_tree_model_get (GTK_TREE_MODEL (priv->store), &iter,
1084
BLUETOOTH_COLUMN_PROPERTIES, &properties, -1);
1085
gtk_tree_path_free (path);
1087
if (properties == NULL)
1090
ret = properties_call_set_sync (properties,
1091
BLUEZ_ADAPTER_INTERFACE,
1093
g_variant_new_variant (g_variant_new_boolean (discoverable)),
1096
g_warning ("Failed to set Discoverable to %d: %s", discoverable, error->message);
1097
g_error_free (error);
1098
} else if (discoverable) {
1099
ret = properties_call_set_sync (properties,
1100
BLUEZ_ADAPTER_INTERFACE,
1101
"DiscoverableTimeout",
1102
g_variant_new_variant (g_variant_new_uint32 (timeout)),
1105
g_warning ("Failed to set DiscoverableTimeout to %d: %s", timeout, error->message);
1106
g_error_free (error);
1110
g_object_unref (properties);
1116
_bluetooth_client_set_default_adapter_discovering (BluetoothClient *client,
1119
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE (client);
1121
GDBusProxy *adapter;
1124
adapter = _bluetooth_client_get_default_adapter (client);
1125
if (adapter == NULL)
1128
get_iter_from_proxy (priv->store, &iter, adapter);
1129
gtk_tree_model_get (GTK_TREE_MODEL (priv->store), &iter,
1130
BLUETOOTH_COLUMN_DISCOVERING, ¤t, -1);
1132
if (current == discover) {
1133
g_object_unref(adapter);
1138
adapter1_call_start_discovery_sync (ADAPTER1 (adapter), NULL, NULL);
1140
adapter1_call_stop_discovery_sync (ADAPTER1 (adapter), NULL, NULL);
1142
g_object_unref(adapter);
1146
_bluetooth_client_get_default_adapter_discovering (BluetoothClient *self)
1148
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE (self);
1153
if (priv->default_adapter == NULL)
1156
path = gtk_tree_row_reference_get_path (priv->default_adapter);
1157
gtk_tree_model_get_iter (GTK_TREE_MODEL (priv->store), &iter, path);
1158
gtk_tree_model_get (GTK_TREE_MODEL (priv->store), &iter, BLUETOOTH_COLUMN_DISCOVERING, &ret, -1);
1159
gtk_tree_path_free (path);
1165
bluetooth_client_get_property (GObject *object,
1170
BluetoothClient *self = BLUETOOTH_CLIENT (object);
1172
switch (property_id) {
1173
case PROP_DEFAULT_ADAPTER:
1174
g_value_set_string (value, _bluetooth_client_get_default_adapter_path (self));
1176
case PROP_DEFAULT_ADAPTER_POWERED:
1177
g_value_set_boolean (value, _bluetooth_client_get_default_adapter_powered (self));
1179
case PROP_DEFAULT_ADAPTER_NAME:
1180
g_value_take_string (value, _bluetooth_client_get_default_adapter_name (self));
1182
case PROP_DEFAULT_ADAPTER_DISCOVERABLE:
1183
g_value_set_boolean (value, _bluetooth_client_get_discoverable (self));
1185
case PROP_DEFAULT_ADAPTER_DISCOVERING:
1186
g_value_set_boolean (value, _bluetooth_client_get_default_adapter_discovering (self));
1189
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
1195
bluetooth_client_set_property (GObject *object,
1197
const GValue *value,
1200
BluetoothClient *self = BLUETOOTH_CLIENT (object);
1202
switch (property_id) {
1203
case PROP_DEFAULT_ADAPTER_DISCOVERABLE:
1204
_bluetooth_client_set_discoverable (self, g_value_get_boolean (value), 0);
1206
case PROP_DEFAULT_ADAPTER_DISCOVERING:
1207
_bluetooth_client_set_default_adapter_discovering (self, g_value_get_boolean (value));
1210
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
1215
static void bluetooth_client_finalize(GObject *object)
1217
BluetoothClient *client = BLUETOOTH_CLIENT (object);
1218
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE (client);
1220
g_bus_unwatch_name (priv->owner_change_id);
1222
g_clear_object (&priv->manager);
1223
g_object_unref (priv->store);
1225
g_clear_pointer (&priv->default_adapter, gtk_tree_row_reference_free);
1227
G_OBJECT_CLASS(bluetooth_client_parent_class)->finalize (object);
1230
static void bluetooth_client_class_init(BluetoothClientClass *klass)
1232
GObjectClass *object_class = G_OBJECT_CLASS (klass);
1234
object_class->finalize = bluetooth_client_finalize;
1235
object_class->get_property = bluetooth_client_get_property;
1236
object_class->set_property = bluetooth_client_set_property;
1239
* BluetoothClient::device-removed:
1240
* @client: a #BluetoothClient object which received the signal
1241
* @device: the D-Bus object path for the now-removed device
1243
* The #BluetoothClient::device-removed signal is launched when a
1244
* device gets removed from the model.
1246
signals[DEVICE_REMOVED] =
1247
g_signal_new ("device-removed",
1248
G_TYPE_FROM_CLASS (klass),
1252
g_cclosure_marshal_VOID__STRING,
1253
G_TYPE_NONE, 1, G_TYPE_STRING);
1256
* BluetoothClient:default-adapter:
1258
* The D-Bus path of the default Bluetooth adapter or %NULL.
1260
g_object_class_install_property (object_class, PROP_DEFAULT_ADAPTER,
1261
g_param_spec_string ("default-adapter", NULL,
1262
"The D-Bus path of the default adapter",
1263
NULL, G_PARAM_READABLE));
1265
* BluetoothClient:default-adapter-powered:
1267
* %TRUE if the default Bluetooth adapter is powered.
1269
g_object_class_install_property (object_class, PROP_DEFAULT_ADAPTER_POWERED,
1270
g_param_spec_boolean ("default-adapter-powered", NULL,
1271
"Whether the default adapter is powered",
1272
FALSE, G_PARAM_READABLE));
1274
* BluetoothClient:default-adapter-discoverable:
1276
* %TRUE if the default Bluetooth adapter is discoverable.
1278
g_object_class_install_property (object_class, PROP_DEFAULT_ADAPTER_DISCOVERABLE,
1279
g_param_spec_boolean ("default-adapter-discoverable", NULL,
1280
"Whether the default adapter is visible by other devices",
1281
FALSE, G_PARAM_READWRITE));
1283
* BluetoothClient:default-adapter-name:
1285
* The name of the default Bluetooth adapter or %NULL.
1287
g_object_class_install_property (object_class, PROP_DEFAULT_ADAPTER_NAME,
1288
g_param_spec_string ("default-adapter-name", NULL,
1289
"The human readable name of the default adapter",
1290
NULL, G_PARAM_READABLE));
1292
* BluetoothClient:default-adapter-discovering:
1294
* %TRUE if the default Bluetooth adapter is discovering.
1296
g_object_class_install_property (object_class, PROP_DEFAULT_ADAPTER_DISCOVERING,
1297
g_param_spec_boolean ("default-adapter-discovering", NULL,
1298
"Whether the default adapter is searching for devices",
1299
FALSE, G_PARAM_READWRITE));
1303
* bluetooth_client_new:
1305
* Returns a reference to the #BluetoothClient singleton. Use g_object_unref() when done with the object.
1307
* Return value: (transfer full): a #BluetoothClient object.
1309
BluetoothClient *bluetooth_client_new(void)
1311
static BluetoothClient *bluetooth_client = NULL;
1313
if (bluetooth_client != NULL)
1314
return g_object_ref(bluetooth_client);
1316
bluetooth_client = BLUETOOTH_CLIENT (g_object_new (BLUETOOTH_TYPE_CLIENT, NULL));
1317
g_object_add_weak_pointer (G_OBJECT (bluetooth_client),
1318
(gpointer) &bluetooth_client);
1320
return bluetooth_client;
1324
* bluetooth_client_get_model:
1325
* @client: a #BluetoothClient object
1327
* Returns an unfiltered #GtkTreeModel representing the adapter and devices available on the system.
1329
* Return value: (transfer full): a #GtkTreeModel object.
1331
GtkTreeModel *bluetooth_client_get_model (BluetoothClient *client)
1333
BluetoothClientPrivate *priv;
1334
GtkTreeModel *model;
1336
g_return_val_if_fail (BLUETOOTH_IS_CLIENT (client), NULL);
1338
priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
1339
model = g_object_ref(priv->store);
1345
* bluetooth_client_get_filter_model:
1346
* @client: a #BluetoothClient object
1347
* @func: a #GtkTreeModelFilterVisibleFunc
1348
* @data: user data to pass to gtk_tree_model_filter_set_visible_func()
1349
* @destroy: a destroy function for gtk_tree_model_filter_set_visible_func()
1351
* Returns a #GtkTreeModelFilter of devices filtered using the @func, @data and @destroy arguments to pass to gtk_tree_model_filter_set_visible_func().
1353
* Return value: (transfer full): a #GtkTreeModel object.
1355
GtkTreeModel *bluetooth_client_get_filter_model (BluetoothClient *client,
1356
GtkTreeModelFilterVisibleFunc func,
1357
gpointer data, GDestroyNotify destroy)
1359
BluetoothClientPrivate *priv;
1360
GtkTreeModel *model;
1362
g_return_val_if_fail (BLUETOOTH_IS_CLIENT (client), NULL);
1364
priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
1365
model = gtk_tree_model_filter_new(GTK_TREE_MODEL(priv->store), NULL);
1367
gtk_tree_model_filter_set_visible_func(GTK_TREE_MODEL_FILTER(model),
1368
func, data, destroy);
1373
static gboolean adapter_filter(GtkTreeModel *model,
1374
GtkTreeIter *iter, gpointer user_data)
1379
gtk_tree_model_get(model, iter, BLUETOOTH_COLUMN_PROXY, &proxy, -1);
1384
active = g_str_equal(BLUEZ_ADAPTER_INTERFACE,
1385
g_dbus_proxy_get_interface_name(proxy));
1387
g_object_unref(proxy);
1393
* bluetooth_client_get_adapter_model:
1394
* @client: a #BluetoothClient object
1396
* Returns a #GtkTreeModelFilter with only adapters present.
1398
* Return value: (transfer full): a #GtkTreeModel object.
1400
GtkTreeModel *bluetooth_client_get_adapter_model (BluetoothClient *client)
1402
return bluetooth_client_get_filter_model (client, adapter_filter,
1407
* bluetooth_client_get_device_model:
1408
* @client: a #BluetoothClient object
1410
* Returns a #GtkTreeModelFilter with only devices belonging to the default adapter listed.
1411
* Note that the model will follow a specific adapter, and will not follow the default adapter.
1412
* Also note that due to the way #GtkTreeModelFilter works, you will probably want to
1413
* monitor signals on the "child-model" #GtkTreeModel to monitor for changes.
1415
* Return value: (transfer full): a #GtkTreeModel object.
1417
GtkTreeModel *bluetooth_client_get_device_model (BluetoothClient *client)
1419
BluetoothClientPrivate *priv;
1420
GtkTreeModel *model;
1423
gboolean cont, found = FALSE;
1425
g_return_val_if_fail (BLUETOOTH_IS_CLIENT (client), NULL);
1427
priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
1428
cont = gtk_tree_model_get_iter_first (GTK_TREE_MODEL(priv->store), &iter);
1430
while (cont == TRUE) {
1431
gboolean is_default;
1433
gtk_tree_model_get (GTK_TREE_MODEL(priv->store), &iter,
1434
BLUETOOTH_COLUMN_DEFAULT, &is_default, -1);
1436
if (is_default == TRUE) {
1441
cont = gtk_tree_model_iter_next (GTK_TREE_MODEL(priv->store), &iter);
1444
if (found == TRUE) {
1445
path = gtk_tree_model_get_path (GTK_TREE_MODEL(priv->store), &iter);
1446
model = gtk_tree_model_filter_new (GTK_TREE_MODEL(priv->store), path);
1447
gtk_tree_path_free (path);
1455
BluetoothClientSetupFunc func;
1456
BluetoothClient *client;
1460
device_pair_callback (GDBusProxy *proxy,
1462
GSimpleAsyncResult *simple)
1464
GError *error = NULL;
1466
if (device1_call_pair_finish (DEVICE1(proxy), res, &error) == FALSE) {
1467
g_debug ("Pair() failed for %s: %s",
1468
g_dbus_proxy_get_object_path (proxy),
1470
g_simple_async_result_take_error (simple, error);
1472
g_simple_async_result_set_op_res_gboolean (simple, TRUE);
1475
g_simple_async_result_complete_in_idle (simple);
1477
g_object_unref (simple);
1481
bluetooth_client_setup_device_finish (BluetoothClient *client,
1486
GSimpleAsyncResult *simple;
1488
simple = (GSimpleAsyncResult *) res;
1490
g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == bluetooth_client_setup_device);
1493
*path = g_object_get_data (G_OBJECT (res), "device-object-path");
1495
if (g_simple_async_result_get_op_res_gboolean (simple))
1497
g_simple_async_result_propagate_error (simple, error);
1502
bluetooth_client_setup_device (BluetoothClient *client,
1505
GCancellable *cancellable,
1506
GAsyncReadyCallback callback,
1509
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
1510
GSimpleAsyncResult *simple;
1512
GtkTreeIter iter, adapter_iter;
1516
g_return_if_fail (BLUETOOTH_IS_CLIENT (client));
1518
simple = g_simple_async_result_new (G_OBJECT (client),
1521
bluetooth_client_setup_device);
1522
g_simple_async_result_set_check_cancellable (simple, cancellable);
1523
g_object_set_data (G_OBJECT (simple), "device-object-path", g_strdup (path));
1525
if (get_iter_from_path (priv->store, &iter, path) == FALSE) {
1526
g_simple_async_result_set_error (simple, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
1527
"Device with object path %s does not exist",
1529
g_simple_async_result_complete_in_idle (simple);
1530
g_object_unref (simple);
1534
gtk_tree_model_get (GTK_TREE_MODEL(priv->store), &iter,
1535
BLUETOOTH_COLUMN_PROXY, &device,
1536
BLUETOOTH_COLUMN_PAIRED, &paired, -1);
1538
if (paired != FALSE &&
1539
gtk_tree_model_iter_parent (GTK_TREE_MODEL(priv->store), &adapter_iter, &iter)) {
1540
GDBusProxy *adapter;
1542
gtk_tree_model_get (GTK_TREE_MODEL(priv->store), &adapter_iter,
1543
BLUETOOTH_COLUMN_PROXY, &adapter,
1545
adapter1_call_remove_device_sync (ADAPTER1 (adapter),
1549
g_warning ("Failed to remove device: %s", err->message);
1552
g_object_unref (adapter);
1556
device1_call_pair (DEVICE1(device),
1558
(GAsyncReadyCallback) device_pair_callback,
1561
g_simple_async_result_set_op_res_gboolean (simple, TRUE);
1562
g_simple_async_result_complete_in_idle (simple);
1563
g_object_unref (simple);
1566
g_object_unref (device);
1570
bluetooth_client_set_trusted (BluetoothClient *client,
1574
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
1575
Properties *properties;
1576
GError *error = NULL;
1580
g_return_val_if_fail (BLUETOOTH_IS_CLIENT (client), FALSE);
1581
g_return_val_if_fail (device != NULL, FALSE);
1583
if (get_iter_from_path (priv->store, &iter, device) == FALSE) {
1584
g_debug ("Couldn't find device '%s' in tree to mark it as trusted", device);
1588
gtk_tree_model_get (GTK_TREE_MODEL (priv->store), &iter,
1589
BLUETOOTH_COLUMN_PROPERTIES, &properties, -1);
1591
if (properties == NULL) {
1592
g_debug ("Couldn't find properties for device '%s' in tree to mark it as trusted", device);
1596
ret = properties_call_set_sync (properties, BLUEZ_DEVICE_INTERFACE, "Trusted",
1597
g_variant_new_variant (g_variant_new_boolean (trusted)),
1600
g_warning ("Failed to set Trusted to %d: %s", trusted, error->message);
1601
g_error_free (error);
1604
g_object_unref (properties);
1609
bluetooth_client_get_device (BluetoothClient *client,
1612
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
1616
if (get_iter_from_path (priv->store, &iter, path) == FALSE) {
1620
gtk_tree_model_get (GTK_TREE_MODEL(priv->store), &iter,
1621
BLUETOOTH_COLUMN_PROXY, &proxy,
1627
connect_callback (GDBusProxy *proxy,
1629
GSimpleAsyncResult *simple)
1632
GError *error = NULL;
1634
retval = device1_call_connect_finish (DEVICE1(proxy), res, &error);
1635
if (retval == FALSE) {
1636
g_debug ("Connect failed for %s: %s",
1637
g_dbus_proxy_get_object_path (proxy), error->message);
1638
g_simple_async_result_take_error (simple, error);
1640
g_debug ("Connect succeeded for %s",
1641
g_dbus_proxy_get_object_path (proxy));
1642
g_simple_async_result_set_op_res_gboolean (simple, retval);
1645
g_simple_async_result_complete_in_idle (simple);
1647
g_object_unref (simple);
1651
disconnect_callback (GDBusProxy *proxy,
1653
GSimpleAsyncResult *simple)
1656
GError *error = NULL;
1658
retval = device1_call_disconnect_finish (DEVICE1(proxy), res, &error);
1659
if (retval == FALSE) {
1660
g_debug ("Disconnect failed for %s: %s",
1661
g_dbus_proxy_get_object_path (proxy),
1663
g_simple_async_result_take_error (simple, error);
1665
g_debug ("Disconnect succeeded for %s",
1666
g_dbus_proxy_get_object_path (proxy));
1667
g_simple_async_result_set_op_res_gboolean (simple, retval);
1670
g_simple_async_result_complete_in_idle (simple);
1672
g_object_unref (simple);
1676
* bluetooth_client_connect_service:
1677
* @client: a #BluetoothClient
1678
* @path: the object path on which to operate
1679
* @connect: Whether try to connect or disconnect from services on a device
1680
* @cancellable: optional #GCancellable object, %NULL to ignore
1681
* @callback: (scope async): a #GAsyncReadyCallback to call when the connection is complete
1682
* @user_data: the data to pass to callback function
1684
* When the connection operation is finished, @callback will be called. You can
1685
* then call bluetooth_client_connect_service_finish() to get the result of the
1689
bluetooth_client_connect_service (BluetoothClient *client,
1692
GCancellable *cancellable,
1693
GAsyncReadyCallback callback,
1696
BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
1698
GSimpleAsyncResult *simple;
1701
g_return_if_fail (BLUETOOTH_IS_CLIENT (client));
1702
g_return_if_fail (path != NULL);
1704
if (get_iter_from_path (priv->store, &iter, path) == FALSE)
1707
gtk_tree_model_get (GTK_TREE_MODEL(priv->store), &iter,
1708
BLUETOOTH_COLUMN_PROXY, &device,
1711
simple = g_simple_async_result_new (G_OBJECT (client),
1714
bluetooth_client_connect_service);
1715
g_simple_async_result_set_check_cancellable (simple, cancellable);
1718
device1_call_connect (DEVICE1(device),
1720
(GAsyncReadyCallback) connect_callback,
1723
device1_call_disconnect (DEVICE1(device),
1725
(GAsyncReadyCallback) disconnect_callback,
1729
g_object_unref (device);
1733
* bluetooth_client_connect_service_finish:
1734
* @client: a #BluetoothClient
1735
* @res: a #GAsyncResult
1738
* Finishes the connection operation. See bluetooth_client_connect_service().
1740
* Returns: %TRUE if the connection operation succeeded, %FALSE otherwise.
1743
bluetooth_client_connect_service_finish (BluetoothClient *client,
1747
GSimpleAsyncResult *simple;
1749
simple = (GSimpleAsyncResult *) res;
1751
g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == bluetooth_client_connect_service);
1753
if (g_simple_async_result_get_op_res_gboolean (simple))
1755
g_simple_async_result_propagate_error (simple, error);
1759
#define BOOL_STR(x) (x ? "True" : "False")
1762
bluetooth_client_dump_device (GtkTreeModel *model,
1766
char *address, *alias, *name, *icon, **uuids;
1767
gboolean is_default, paired, trusted, connected, discoverable, discovering, powered, is_adapter;
1771
gtk_tree_model_get (model, iter,
1772
BLUETOOTH_COLUMN_ADDRESS, &address,
1773
BLUETOOTH_COLUMN_ALIAS, &alias,
1774
BLUETOOTH_COLUMN_NAME, &name,
1775
BLUETOOTH_COLUMN_TYPE, &type,
1776
BLUETOOTH_COLUMN_ICON, &icon,
1777
BLUETOOTH_COLUMN_DEFAULT, &is_default,
1778
BLUETOOTH_COLUMN_PAIRED, &paired,
1779
BLUETOOTH_COLUMN_TRUSTED, &trusted,
1780
BLUETOOTH_COLUMN_CONNECTED, &connected,
1781
BLUETOOTH_COLUMN_DISCOVERABLE, &discoverable,
1782
BLUETOOTH_COLUMN_DISCOVERING, &discovering,
1783
BLUETOOTH_COLUMN_POWERED, &powered,
1784
BLUETOOTH_COLUMN_UUIDS, &uuids,
1785
BLUETOOTH_COLUMN_PROXY, &proxy,
1789
basename = g_path_get_basename(g_dbus_proxy_get_object_path(proxy));
1790
is_adapter = !g_str_has_prefix (basename, "dev_");
1793
is_adapter = !gtk_tree_model_iter_parent (model, &parent, iter);
1796
if (is_adapter != FALSE) {
1798
g_print ("Adapter: %s (%s)\n", name, address);
1800
g_print ("\tDefault adapter\n");
1801
g_print ("\tD-Bus Path: %s\n", proxy ? g_dbus_proxy_get_object_path (proxy) : "(none)");
1802
g_print ("\tDiscoverable: %s\n", BOOL_STR (discoverable));
1804
g_print ("\tDiscovery in progress\n");
1805
g_print ("\t%s\n", powered ? "Is powered" : "Is not powered");
1808
g_print ("Device: %s (%s)\n", alias, address);
1809
g_print ("\tD-Bus Path: %s\n", proxy ? g_dbus_proxy_get_object_path (proxy) : "(none)");
1810
g_print ("\tType: %s Icon: %s\n", bluetooth_type_to_string (type), icon);
1811
g_print ("\tPaired: %s Trusted: %s Connected: %s\n", BOOL_STR(paired), BOOL_STR(trusted), BOOL_STR(connected));
1812
if (uuids != NULL) {
1814
g_print ("\tUUIDs: ");
1815
for (i = 0; uuids[i] != NULL; i++)
1816
g_print ("%s ", uuids[i]);
1825
g_clear_object (&proxy);