3 * BlueZ - Bluetooth protocol stack for Linux
5 * Copyright (C) 2011 ST-Ericsson SA
7 * Author: Szymon Janc <szymon.janc@tieto.com> for ST-Ericsson
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program 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
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
33 #include <bluetooth/bluetooth.h>
34 #include <bluetooth/hci.h>
35 #include <bluetooth/sdp.h>
42 #include "dbus-common.h"
47 #define OOB_INTERFACE "org.bluez.OutOfBand"
50 struct btd_adapter *adapter;
54 static GSList *oob_requests = NULL;
55 static DBusConnection *connection = NULL;
57 static gint oob_request_cmp(gconstpointer a, gconstpointer b)
59 const struct oob_request *data = a;
60 const struct btd_adapter *adapter = b;
62 return data->adapter != adapter;
65 static struct oob_request *find_oob_request(struct btd_adapter *adapter)
69 match = g_slist_find_custom(oob_requests, adapter, oob_request_cmp);
77 static void read_local_data_complete(struct btd_adapter *adapter, uint8_t *hash,
80 struct DBusMessage *reply;
81 struct oob_request *oob_request;
83 oob_request = find_oob_request(adapter);
87 if (hash && randomizer)
88 reply = g_dbus_create_reply(oob_request->msg,
89 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &hash, 16,
90 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &randomizer, 16,
93 reply = btd_error_failed(oob_request->msg,
94 "Failed to read local OOB data.");
96 oob_requests = g_slist_remove(oob_requests, oob_request);
97 dbus_message_unref(oob_request->msg);
101 error("Couldn't allocate D-Bus message");
105 if (!g_dbus_send_message(connection, reply))
106 error("D-Bus send failed");
109 static DBusMessage *read_local_data(DBusConnection *conn, DBusMessage *msg,
112 struct btd_adapter *adapter = data;
113 struct oob_request *oob_request;
115 if (find_oob_request(adapter))
116 return btd_error_in_progress(msg);
118 if (btd_adapter_read_local_oob_data(adapter))
119 return btd_error_failed(msg, "Request failed.");
121 oob_request = g_new(struct oob_request, 1);
122 oob_request->adapter = adapter;
123 oob_requests = g_slist_append(oob_requests, oob_request);
124 oob_request->msg = dbus_message_ref(msg);
129 static DBusMessage *add_remote_data(DBusConnection *conn, DBusMessage *msg,
132 struct btd_adapter *adapter = data;
133 uint8_t *hash, *randomizer;
138 if (!dbus_message_get_args(msg, NULL,
139 DBUS_TYPE_STRING, &addr,
140 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &hash, &hlen,
141 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &randomizer, &rlen,
143 return btd_error_invalid_args(msg);
145 if (hlen != 16 || rlen != 16 || bachk(addr))
146 return btd_error_invalid_args(msg);
148 str2ba(addr, &bdaddr);
150 if (btd_adapter_add_remote_oob_data(adapter, &bdaddr, hash, randomizer))
151 return btd_error_failed(msg, "Request failed");
153 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
156 static DBusMessage *remove_remote_data(DBusConnection *conn, DBusMessage *msg,
159 struct btd_adapter *adapter = data;
163 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &addr,
165 return btd_error_invalid_args(msg);
168 return btd_error_invalid_args(msg);
170 str2ba(addr, &bdaddr);
172 if (btd_adapter_remove_remote_oob_data(adapter, &bdaddr))
173 return btd_error_failed(msg, "Request failed");
175 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
178 static GDBusMethodTable oob_methods[] = {
179 {"AddRemoteData", "sayay", "", add_remote_data},
180 {"RemoveRemoteData", "s", "", remove_remote_data},
181 {"ReadLocalData", "", "ayay", read_local_data,
182 G_DBUS_METHOD_FLAG_ASYNC},
186 static int oob_probe(struct btd_adapter *adapter)
188 const char *path = adapter_get_path(adapter);
190 if (!g_dbus_register_interface(connection, path, OOB_INTERFACE,
191 oob_methods, NULL, NULL, adapter, NULL)) {
192 error("OOB interface init failed on path %s", path);
199 static void oob_remove(struct btd_adapter *adapter)
201 read_local_data_complete(adapter, NULL, NULL);
203 g_dbus_unregister_interface(connection, adapter_get_path(adapter),
207 static struct btd_adapter_driver oob_driver = {
210 .remove = oob_remove,
213 static int dbusoob_init(void)
215 DBG("Setup dbusoob plugin");
217 connection = get_dbus_connection();
219 oob_register_cb(read_local_data_complete);
221 return btd_register_adapter_driver(&oob_driver);
224 static void dbusoob_exit(void)
226 DBG("Cleanup dbusoob plugin");
228 manager_foreach_adapter((adapter_cb) oob_remove, NULL);
230 btd_unregister_adapter_driver(&oob_driver);
233 BLUETOOTH_PLUGIN_DEFINE(dbusoob, VERSION, BLUETOOTH_PLUGIN_PRIORITY_DEFAULT,
234 dbusoob_init, dbusoob_exit)