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