2
* oFono - Open Source Telephony
4
* Copyright (C) 2008-2012 Intel Corporation. All rights reserved.
5
* Copyright (C) 2012 BMW Car IT GmbH. All rights reserved.
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.
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.
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
26
#include <sys/types.h>
34
#include "plugins/bluetooth.h"
38
static GHashTable *bluetooth_hash;
40
struct bluetooth_device {
41
struct dundee_device *device;
47
DBusPendingCall *call;
50
static void bt_disconnect(struct dundee_device *device,
51
dundee_device_disconnect_cb_t cb, void *data)
53
struct bluetooth_device *bt = dundee_device_get_data(device);
57
CALLBACK_WITH_SUCCESS(cb, data);
60
static void bt_connect_reply(DBusPendingCall *call, gpointer user_data)
62
struct cb_data *cbd = user_data;
63
dundee_device_connect_cb_t cb = cbd->cb;
64
struct bluetooth_device *bt = cbd->user;
71
reply = dbus_pending_call_steal_reply(call);
75
dbus_error_init(&derr);
76
if (dbus_set_error_from_message(&derr, reply)) {
77
DBG("Connection to bt serial returned with error: %s, %s",
78
derr.name, derr.message);
80
dbus_error_free(&derr);
82
CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
86
dbus_message_get_args(reply, NULL, DBUS_TYPE_UNIX_FD, &fd,
89
DBG("%p fd %d", bt, fd);
92
CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
96
CALLBACK_WITH_SUCCESS(cb, fd, cbd->data);
99
dbus_message_unref(reply);
103
static void bt_connect(struct dundee_device *device,
104
dundee_device_connect_cb_t cb, void *data)
106
struct bluetooth_device *bt = dundee_device_get_data(device);
107
struct cb_data *cbd = cb_data_new(cb, data);
108
char *profile = "dun";
115
status = bluetooth_send_with_reply(bt->path,
116
BLUEZ_SERIAL_INTERFACE, "ConnectFD",
117
&bt->call, bt_connect_reply,
118
cbd, NULL, DBUS_TIMEOUT,
119
DBUS_TYPE_STRING, &profile,
126
CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
129
struct dundee_device_driver bluetooth_driver = {
131
.connect = bt_connect,
132
.disconnect = bt_disconnect,
135
static int bt_probe(const char *path, const char *dev_addr,
136
const char *adapter_addr, const char *alias)
138
struct bluetooth_device *bt;
139
struct dundee_device *device;
144
/* We already have this device in our hash, ignore */
145
if (g_hash_table_lookup(bluetooth_hash, path) != NULL)
148
ofono_info("Using device: %s, devaddr: %s, adapter: %s",
149
path, dev_addr, adapter_addr);
152
bluetooth_create_path(dev_addr, adapter_addr, buf + 4, sizeof(buf) - 4);
154
bt = g_try_new0(struct bluetooth_device, 1);
160
device = dundee_device_create(&bluetooth_driver);
164
dundee_device_set_data(device, bt);
166
bt->path = g_strdup(path);
167
if (bt->path == NULL)
170
bt->address = g_strdup(dev_addr);
171
if (bt->address == NULL)
174
bt->name = g_strdup(alias);
175
if (bt->name == NULL)
178
dundee_device_set_name(device, bt->name);
180
if (dundee_device_register(device) < 0) {
186
g_hash_table_insert(bluetooth_hash, g_strdup(path), bt);
199
static void destroy_device(gpointer user)
201
struct bluetooth_device *bt = user;
205
if (bt->call != NULL)
206
dbus_pending_call_cancel(bt->call);
214
static gboolean bt_remove_device(gpointer key, gpointer value,
217
struct bluetooth_device *bt = value;
218
const char *path = key;
219
const char *prefix = user_data;
223
if (prefix && g_str_has_prefix(path, prefix) == FALSE)
226
dundee_device_unregister(bt->device);
231
static void bt_remove(const char *prefix)
235
if (bluetooth_hash == NULL)
238
g_hash_table_foreach_remove(bluetooth_hash, bt_remove_device,
242
static void bt_set_alias(const char *path, const char *alias)
244
struct bluetooth_device *bt;
248
if (path == NULL || alias == NULL)
251
bt = g_hash_table_lookup(bluetooth_hash, path);
256
bt->name = g_strdup(alias);
258
dundee_device_set_name(bt->device, bt->name);
261
static struct bluetooth_profile dun_profile = {
265
.set_alias = bt_set_alias,
268
int __dundee_bluetooth_init(void)
274
err = bluetooth_register_uuid(DUN_GW_UUID, &dun_profile);
278
bluetooth_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
279
g_free, destroy_device);
284
void __dundee_bluetooth_cleanup(void)
288
bluetooth_unregister_uuid(DUN_GW_UUID);
289
g_hash_table_destroy(bluetooth_hash);