c09e4a5e69b888dd76fe73b2e60716fc71435289
[connman] / plugins / bluetooth.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2007-2008  Intel Corporation. All rights reserved.
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License version 2 as
9  *  published by the Free Software Foundation.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <errno.h>
27
28 #include <gdbus.h>
29
30 #include <connman/plugin.h>
31 #include <connman/device.h>
32 #include <connman/log.h>
33
34 #define BLUEZ_SERVICE "org.bluez"
35
36 #define TIMEOUT 5000
37
38 static int bluetooth_probe(struct connman_device *device)
39 {
40         DBG("device %p", device);
41
42         return 0;
43 }
44
45 static void bluetooth_remove(struct connman_device *device)
46 {
47         DBG("device %p", device);
48 }
49
50 static struct connman_device_driver bluetooth_driver = {
51         .name   = "bluetooth",
52         .type   = CONNMAN_DEVICE_TYPE_BLUETOOTH,
53         .probe  = bluetooth_probe,
54         .remove = bluetooth_remove,
55 };
56
57 static GSList *device_list = NULL;
58
59 static void adapters_reply(DBusPendingCall *call, void *user_data)
60 {
61         DBusMessage *reply;
62         DBusError error;
63         char **adapters;
64         int i, num_adapters;
65
66         DBG("");
67
68         reply = dbus_pending_call_steal_reply(call);
69
70         dbus_error_init(&error);
71
72         if (dbus_message_get_args(reply, &error,
73                                 DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH,
74                                                 &adapters, &num_adapters,
75                                                 DBUS_TYPE_INVALID) == FALSE) {
76                 if (dbus_error_is_set(&error) == TRUE) {
77                         connman_error("%s", error.message);
78                         dbus_error_free(&error);
79                 } else
80                         connman_error("Wrong arguments for adapter list");
81                 goto done;
82         }
83
84         for (i = 0; i < num_adapters; i++) {
85                 struct connman_element *device;
86
87                 device = connman_element_create(NULL);
88                 device->type = CONNMAN_ELEMENT_TYPE_DEVICE;
89                 device->subtype = CONNMAN_ELEMENT_SUBTYPE_BLUETOOTH;
90
91                 device->name = g_path_get_basename(adapters[i]);
92
93                 connman_element_register(device, NULL);
94                 device_list = g_slist_append(device_list, device);
95         }
96
97         g_strfreev(adapters);
98
99 done:
100         dbus_message_unref(reply);
101 }
102
103 static void bluetooth_connect(DBusConnection *connection, void *user_data)
104 {
105         DBusMessage *message;
106         DBusPendingCall *call;
107
108         DBG("connection %p", connection);
109
110         message = dbus_message_new_method_call(BLUEZ_SERVICE, "/",
111                                         "org.bluez.Manager", "ListAdapters");
112         if (message == NULL)
113                 return;
114
115         if (dbus_connection_send_with_reply(connection, message,
116                                                 &call, TIMEOUT) == FALSE) {
117                 connman_error("Failed to get Bluetooth adapters");
118                 dbus_message_unref(message);
119                 return;
120         }
121
122         dbus_pending_call_set_notify(call, adapters_reply, NULL, NULL);
123
124         dbus_message_unref(message);
125 }
126
127 static void bluetooth_disconnect(DBusConnection *connection, void *user_data)
128 {
129         GSList *list;
130
131         DBG("connection %p", connection);
132
133         for (list = device_list; list; list = list->next) {
134                 struct connman_element *device = list->data;
135
136                 connman_element_unregister(device);
137                 connman_element_unref(device);
138         }
139
140         g_slist_free(device_list);
141         device_list = NULL;
142 }
143
144 static DBusConnection *connection;
145 static guint watch;
146
147 static int bluetooth_init(void)
148 {
149         int err;
150
151         connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
152         if (connection == NULL)
153                 return -EIO;
154
155         err = connman_device_driver_register(&bluetooth_driver);
156         if (err < 0) {
157                 dbus_connection_unref(connection);
158                 return -EIO;
159         }
160
161         watch = g_dbus_add_service_watch(connection, BLUEZ_SERVICE,
162                         bluetooth_connect, bluetooth_disconnect, NULL, NULL);
163         if (watch == 0) {
164                 connman_device_driver_unregister(&bluetooth_driver);
165                 dbus_connection_unref(connection);
166                 return -EIO;
167         }
168
169         if (g_dbus_check_service(connection, BLUEZ_SERVICE) == TRUE)
170                 bluetooth_connect(connection, NULL);
171
172         return 0;
173 }
174
175 static void bluetooth_exit(void)
176 {
177         g_dbus_remove_watch(connection, watch);
178
179         connman_device_driver_unregister(&bluetooth_driver);
180
181         dbus_connection_unref(connection);
182 }
183
184 CONNMAN_PLUGIN_DEFINE(bluetooth, "Bluetooth technology plugin", VERSION,
185                                                 bluetooth_init, bluetooth_exit)