/* * fmrxd - a daemon to enable and multiplex access to the N950/N9 radio tuner * Copyright (C) 2011 Javier S. Pedro * * Mostly based on ohm-plugins-misc from MeeGo Multimedia * Copyright (C) 2010 Nokia Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include #include #include #include #include #include "fmrxd.h" static gboolean disable_bt_func(gpointer data) { int dd; g_debug("Now disabling BT"); dd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); if (dd == -1) { g_message("Failed to open HCI socket: %s", strerror(errno)); return FALSE; } if (ioctl(dd, HCIDEVDOWN, BT_DEV_ID) < 0 && errno != EALREADY) { g_message("Failed to turn Bluetooth device off: %s", strerror(errno)); } close(dd); return FALSE; } bool configure_bt_muxer(bool on) { struct sockaddr_hci a; int dd; bool was_up; /* The magic numbers: */ const short ocf = 0x00; const short ogf = 0x3f; char cmd[4] = { 0xf3, 0x88, 0x01, on ? 0x02 : 0x01 }; /* Open HCI socket. */ dd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); if (dd == -1) { g_warning("Failed to open HCI socket: %s", strerror(errno)); return false; } /* Try to turn the specificied BT device on. */ if (ioctl(dd, HCIDEVUP, BT_DEV_ID) < 0) { if (errno == EALREADY) { /* The BT device was found to be already on; no need to turn it off later. */ was_up = true; } else { g_warning("Failed to turn Bluetooth device on: %s", strerror(errno)); goto failed; } } else { /* Turned on succesfully. */ g_debug("Turned on BT"); was_up = false; } /* Bind HCI socket to this device. */ memset(&a, 0, sizeof(a)); a.hci_family = AF_BLUETOOTH; a.hci_dev = BT_DEV_ID; if (bind(dd, (struct sockaddr *) &a, sizeof(a)) < 0) { g_warning("Failed to bind HCI socket: %s", strerror(errno)); goto failed; } /* Now send the magic command. */ if (hci_send_cmd(dd, ogf, ocf, sizeof(cmd), cmd) < 0) { g_warning("Failed to send magic HCI command: %s", strerror(errno)); goto failed; } g_debug("Muxer config changed to 0x%x", cmd[3]); close(dd); if (!was_up) { /* Try to shut down bluetooth if we enabled it. */ /* Give ample time for everything to be setup though. */ g_timeout_add_seconds(1, disable_bt_func, NULL); } return true; failed: close(dd); return false; }