mgmtops.c revision 93d8dc9eed86c85c6213e7cbd785170b9ee2d311
1/*
2 *
3 *  BlueZ - Bluetooth protocol stack for Linux
4 *
5 *  Copyright (C) 2010  Nokia Corporation
6 *  Copyright (C) 2010  Marcel Holtmann <marcel@holtmann.org>
7 *
8 *  This program is free software; you can redistribute it and/or modify
9 *  it under the terms of the GNU General Public License as published by
10 *  the Free Software Foundation; either version 2 of the License, or
11 *  (at your option) any later version.
12 *
13 *  This program is distributed in the hope that it will be useful,
14 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *  GNU General Public License for more details.
17 *
18 *  You should have received a copy of the GNU General Public License
19 *  along with this program; if not, write to the Free Software
20 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21 *
22 */
23
24#ifdef HAVE_CONFIG_H
25#include <config.h>
26#endif
27
28#include <stdio.h>
29#include <errno.h>
30#include <unistd.h>
31#include <stdlib.h>
32#include <sys/types.h>
33#include <sys/ioctl.h>
34#include <sys/wait.h>
35
36#include <glib.h>
37
38#include <bluetooth/bluetooth.h>
39#include <bluetooth/hci.h>
40#include <bluetooth/mgmt.h>
41
42#include "plugin.h"
43#include "log.h"
44#include "manager.h"
45#include "adapter.h"
46#include "device.h"
47#include "event.h"
48
49#define MGMT_BUF_SIZE 1024
50
51static int mgmt_sock = -1;
52static guint mgmt_watch = 0;
53
54static gboolean mgmt_event(GIOChannel *io, GIOCondition cond, gpointer user_data)
55{
56	char buf[MGMT_BUF_SIZE];
57	int sk;
58	ssize_t ret;
59
60	if (cond & G_IO_NVAL)
61		return FALSE;
62
63	sk = g_io_channel_unix_get_fd(io);
64
65	if (cond & (G_IO_ERR | G_IO_HUP)) {
66		error("Error on management socket");
67		return FALSE;
68	}
69
70	ret = read(sk, buf, sizeof(buf));
71	if (ret < 0) {
72		error("Unable to read from management socket: %s (%d)",
73						strerror(errno), errno);
74		return TRUE;
75	}
76
77	DBG("Received %zd bytes from management socket", ret);
78
79	return TRUE;
80}
81
82static int mgmt_setup(void)
83{
84	struct hci_mgmt_hdr hdr;
85	struct sockaddr_hci addr;
86	GIOChannel *io;
87	GIOCondition condition;
88	int dd, err;
89
90	dd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
91	if (dd < 0)
92		return -errno;
93
94	memset(&addr, 0, sizeof(addr));
95	addr.hci_family = AF_BLUETOOTH;
96	addr.hci_dev = HCI_DEV_NONE;
97	addr.hci_channel = HCI_CHANNEL_CONTROL;
98
99	if (bind(dd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
100		err = -errno;
101		goto fail;
102	}
103
104	memset(&hdr, 0, sizeof(hdr));
105	hdr.opcode = HCI_MGMT_OP_READ_VERSION;
106	if (write(dd, &hdr, sizeof(hdr)) < 0) {
107		err = -errno;
108		goto fail;
109	}
110
111	io = g_io_channel_unix_new(dd);
112	condition = G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL;
113	mgmt_watch = g_io_add_watch(io, condition, mgmt_event, NULL);
114	g_io_channel_unref(io);
115
116	mgmt_sock = dd;
117
118	info("Bluetooth Management interface initialized");
119
120	return 0;
121
122fail:
123	close(dd);
124	return err;
125}
126
127static void mgmt_cleanup(void)
128{
129	if (mgmt_sock >= 0) {
130		close(mgmt_sock);
131		mgmt_sock = -1;
132	}
133
134	if (mgmt_watch > 0) {
135		g_source_remove(mgmt_watch);
136		mgmt_watch = 0;
137	}
138}
139
140static int mgmt_start(int index)
141{
142	DBG("index %d", index);
143	return 0;
144}
145
146static int mgmt_stop(int index)
147{
148	DBG("index %d", index);
149	return 0;
150}
151
152static int mgmt_powered(int index, gboolean powered)
153{
154	DBG("index %d powered %d", index, powered);
155	return 0;
156}
157
158static int mgmt_connectable(int index)
159{
160	DBG("index %d", index);
161	return 0;
162}
163
164static int mgmt_discoverable(int index)
165{
166	DBG("index %d", index);
167	return 0;
168}
169
170static int mgmt_set_class(int index, uint32_t class)
171{
172	DBG("index %d class %u", index, class);
173	return 0;
174}
175
176static int mgmt_set_limited_discoverable(int index, uint32_t class,
177							gboolean limited)
178{
179	DBG("index %d class %u, limited %d", index, class, limited);
180	return 0;
181}
182
183static int mgmt_start_inquiry(int index, uint8_t length, gboolean periodic)
184{
185	DBG("index %d length %u periodic %d", index, length, periodic);
186	return 0;
187}
188
189static int mgmt_stop_inquiry(int index)
190{
191	DBG("index %d", index);
192	return 0;
193}
194
195static int mgmt_start_scanning(int index)
196{
197	DBG("index %d", index);
198	return 0;
199}
200
201static int mgmt_stop_scanning(int index)
202{
203	DBG("index %d", index);
204	return 0;
205}
206
207static int mgmt_resolve_name(int index, bdaddr_t *bdaddr)
208{
209	char addr[18];
210
211	ba2str(bdaddr, addr);
212	DBG("index %d addr %s", index, addr);
213
214	return 0;
215}
216
217static int mgmt_set_name(int index, const char *name)
218{
219	DBG("index %d, name %s", index, name);
220	return 0;
221}
222
223static int mgmt_read_name(int index)
224{
225	DBG("index %d", index);
226	return 0;
227}
228
229static int mgmt_cancel_resolve_name(int index, bdaddr_t *bdaddr)
230{
231	char addr[18];
232
233	ba2str(bdaddr, addr);
234	DBG("index %d addr %s", index, addr);
235
236	return 0;
237}
238
239static int mgmt_fast_connectable(int index, gboolean enable)
240{
241	DBG("index %d enable %d", index, enable);
242	return 0;
243}
244
245static int mgmt_read_clock(int index, int handle, int which, int timeout,
246					uint32_t *clock, uint16_t *accuracy)
247{
248	DBG("index %d handle %d which %d timeout %d", index, handle,
249							which, timeout);
250	return 0;
251}
252
253static int mgmt_conn_handle(int index, const bdaddr_t *bdaddr, int *handle)
254{
255	char addr[18];
256
257	ba2str(bdaddr, addr);
258	DBG("index %d addr %s", index, addr);
259
260	return 0;
261}
262
263static int mgmt_write_eir_data(int index, uint8_t *data)
264{
265	DBG("index %d", index);
266	return 0;
267}
268
269static int mgmt_read_bdaddr(int index, bdaddr_t *bdaddr)
270{
271	char addr[18];
272
273	ba2str(bdaddr, addr);
274	DBG("index %d addr %s", index, addr);
275
276	return 0;
277}
278
279static int mgmt_set_event_mask(int index, uint8_t *events, size_t count)
280{
281	DBG("index %d", index);
282	return 0;
283}
284
285static int mgmt_write_inq_mode(int index, uint8_t mode)
286{
287	DBG("index %d mode %u", index, mode);
288	return 0;
289}
290
291static int mgmt_read_inq_tx_pwr(int index)
292{
293	DBG("index %d", index);
294	return 0;
295}
296
297static int mgmt_block_device(int index, bdaddr_t *bdaddr)
298{
299	char addr[18];
300
301	ba2str(bdaddr, addr);
302	DBG("index %d addr %s", index, addr);
303
304	return 0;
305}
306
307static int mgmt_unblock_device(int index, bdaddr_t *bdaddr)
308{
309	char addr[18];
310
311	ba2str(bdaddr, addr);
312	DBG("index %d addr %s", index, addr);
313
314	return 0;
315}
316
317static int mgmt_get_conn_list(int index, GSList **conns)
318{
319	DBG("index %d", index);
320	return 0;
321}
322
323static int mgmt_read_local_version(int index, struct hci_version *ver)
324{
325	DBG("index %d", index);
326	return 0;
327}
328
329static int mgmt_read_local_features(int index, uint8_t *features)
330{
331	DBG("index %d", index);
332	return  0;
333}
334
335static int mgmt_read_local_ext_features(int index)
336{
337	DBG("index %d", index);
338	return 0;
339}
340
341static int mgmt_init_ssp_mode(int index, uint8_t *mode)
342{
343	DBG("index %d", index);
344	return 0;
345}
346
347static int mgmt_read_link_policy(int index)
348{
349	DBG("index %d", index);
350	return 0;
351}
352
353static int mgmt_disconnect(int index, uint16_t handle)
354{
355	DBG("index %d handle %u", index, handle);
356	return 0;
357}
358
359static int mgmt_remove_bonding(int index, bdaddr_t *bdaddr)
360{
361	char addr[18];
362
363	ba2str(bdaddr, addr);
364	DBG("index %d addr %s", index, addr);
365
366	return 0;
367}
368
369static int mgmt_request_authentication(int index, uint16_t handle,
370							uint8_t *status)
371{
372	DBG("index %d handle %u", index, handle);
373	return 0;
374}
375
376static int mgmt_pincode_reply(int index, bdaddr_t *bdaddr, const char *pin)
377{
378	char addr[18];
379
380	ba2str(bdaddr, addr);
381	DBG("index %d addr %s pin %s", index, addr, pin);
382
383	return 0;
384}
385
386static int mgmt_confirm_reply(int index, bdaddr_t *bdaddr, gboolean success)
387{
388	char addr[18];
389
390	ba2str(bdaddr, addr);
391	DBG("index %d addr %s success %d", index, addr, success);
392
393	return 0;
394}
395
396static int mgmt_passkey_reply(int index, bdaddr_t *bdaddr, uint32_t passkey)
397{
398	char addr[18];
399
400	ba2str(bdaddr, addr);
401	DBG("index %d addr %s passkey %06u", index, addr, passkey);
402
403	return 0;
404}
405
406static int mgmt_get_auth_info(int index, bdaddr_t *bdaddr, uint8_t *auth)
407{
408	char addr[18];
409
410	ba2str(bdaddr, addr);
411	DBG("index %d addr %s", index, addr);
412
413	return 0;
414}
415
416static int mgmt_read_scan_enable(int index)
417{
418	DBG("index %d", index);
419	return 0;
420}
421
422static int mgmt_read_ssp_mode(int index)
423{
424	DBG("index %d", index);
425	return 0;
426}
427
428static int mgmt_write_le_host(int index, uint8_t le, uint8_t simul)
429{
430	DBG("index %d le %u simul %u", index, le, simul);
431	return 0;
432}
433
434static int mgmt_get_remote_version(int index, uint16_t handle,
435							gboolean delayed)
436{
437	DBG("index %d handle %u delayed %d", index, handle, delayed);
438	return 0;
439}
440
441static int mgmt_encrypt_link(int index, bdaddr_t *dst, bt_hci_result_t cb,
442							gpointer user_data)
443{
444	char addr[18];
445
446	ba2str(dst, addr);
447	DBG("index %d addr %s", index, addr);
448
449	return 0;
450}
451
452static struct btd_adapter_ops mgmt_ops = {
453	.setup = mgmt_setup,
454	.cleanup = mgmt_cleanup,
455	.start = mgmt_start,
456	.stop = mgmt_stop,
457	.set_powered = mgmt_powered,
458	.set_connectable = mgmt_connectable,
459	.set_discoverable = mgmt_discoverable,
460	.set_limited_discoverable = mgmt_set_limited_discoverable,
461	.start_inquiry = mgmt_start_inquiry,
462	.stop_inquiry = mgmt_stop_inquiry,
463	.start_scanning = mgmt_start_scanning,
464	.stop_scanning = mgmt_stop_scanning,
465	.resolve_name = mgmt_resolve_name,
466	.cancel_resolve_name = mgmt_cancel_resolve_name,
467	.set_name = mgmt_set_name,
468	.read_name = mgmt_read_name,
469	.set_class = mgmt_set_class,
470	.set_fast_connectable = mgmt_fast_connectable,
471	.read_clock = mgmt_read_clock,
472	.get_conn_handle = mgmt_conn_handle,
473	.write_eir_data = mgmt_write_eir_data,
474	.read_bdaddr = mgmt_read_bdaddr,
475	.set_event_mask = mgmt_set_event_mask,
476	.write_inq_mode = mgmt_write_inq_mode,
477	.read_inq_tx_pwr = mgmt_read_inq_tx_pwr,
478	.block_device = mgmt_block_device,
479	.unblock_device = mgmt_unblock_device,
480	.get_conn_list = mgmt_get_conn_list,
481	.read_local_version = mgmt_read_local_version,
482	.read_local_features = mgmt_read_local_features,
483	.read_local_ext_features = mgmt_read_local_ext_features,
484	.init_ssp_mode = mgmt_init_ssp_mode,
485	.read_link_policy = mgmt_read_link_policy,
486	.disconnect = mgmt_disconnect,
487	.remove_bonding = mgmt_remove_bonding,
488	.request_authentication = mgmt_request_authentication,
489	.pincode_reply = mgmt_pincode_reply,
490	.confirm_reply = mgmt_confirm_reply,
491	.passkey_reply = mgmt_passkey_reply,
492	.get_auth_info = mgmt_get_auth_info,
493	.read_scan_enable = mgmt_read_scan_enable,
494	.read_ssp_mode = mgmt_read_ssp_mode,
495	.write_le_host = mgmt_write_le_host,
496	.get_remote_version = mgmt_get_remote_version,
497	.encrypt_link = mgmt_encrypt_link,
498};
499
500static int mgmt_init(void)
501{
502	return btd_register_adapter_ops(&mgmt_ops, TRUE);
503}
504
505static void mgmt_exit(void)
506{
507	btd_adapter_cleanup_ops(&mgmt_ops);
508}
509
510BLUETOOTH_PLUGIN_DEFINE(mgmtops, VERSION,
511		BLUETOOTH_PLUGIN_PRIORITY_LOW, mgmt_init, mgmt_exit)
512