diff --git a/0001-Add-rfkill-plugin.patch b/0001-Add-rfkill-plugin.patch new file mode 100644 index 0000000..e18b9b0 --- /dev/null +++ b/0001-Add-rfkill-plugin.patch @@ -0,0 +1,291 @@ +From bf8b7c07542bd7acb4f9f98ba2165475f0ad9d65 Mon Sep 17 00:00:00 2001 +From: Bastien Nocera +Date: Tue, 28 Jul 2009 17:25:34 +0100 +Subject: [PATCH] Add rfkill plugin + +The plugin allows us to restore the previous power state on +adapters when the killswitch on them has been unblocked. +--- + plugins/Makefile.am | 3 + + plugins/rfkill.c | 199 +++++++++++++++++++++++++++++++++++++++++++++++++++ + src/adapter.c | 23 ++++-- + src/adapter.h | 1 + + 4 files changed, 219 insertions(+), 7 deletions(-) + create mode 100644 plugins/rfkill.c + +diff --git a/plugins/Makefile.am b/plugins/Makefile.am +index 9d9f970..9ba8180 100644 +--- a/plugins/Makefile.am ++++ b/plugins/Makefile.am +@@ -15,6 +15,9 @@ endif + builtin_modules += hciops + builtin_sources += hciops.c + ++builtin_modules += rfkill ++builtin_sources += rfkill.c ++ + if NETLINK + plugin_LTLIBRARIES += netlink.la + netlink_la_LIBADD = @NETLINK_LIBS@ +diff --git a/plugins/rfkill.c b/plugins/rfkill.c +new file mode 100644 +index 0000000..fad8b47 +--- /dev/null ++++ b/plugins/rfkill.c +@@ -0,0 +1,199 @@ ++/* ++ * ++ * BlueZ - Bluetooth protocol stack for Linux ++ * ++ * Copyright (C) 2009 Bastien Nocera ++ * Copyright (C) 2007-2009 Intel Corporation. All rights reserved. ++ * ++ * Author: ++ * Bastien Nocera , based on code by ++ * Johannes Berg ++ * ++ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA ++ * ++ */ ++ ++#ifdef HAVE_CONFIG_H ++#include ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include ++#include ++#include ++ ++#include "hcid.h" ++#include "plugin.h" ++#include "logging.h" ++ ++#include "manager.h" ++#include "adapter.h" ++#include "device.h" ++ ++enum rfkill_type { ++ RFKILL_TYPE_ALL = 0, ++ RFKILL_TYPE_WLAN, ++ RFKILL_TYPE_BLUETOOTH, ++ RFKILL_TYPE_UWB, ++ RFKILL_TYPE_WIMAX, ++ RFKILL_TYPE_WWAN, ++}; ++ ++enum rfkill_operation { ++ RFKILL_OP_ADD = 0, ++ RFKILL_OP_DEL, ++ RFKILL_OP_CHANGE, ++ RFKILL_OP_CHANGE_ALL, ++}; ++ ++struct rfkill_event { ++ uint32_t idx; ++ uint8_t type; ++ uint8_t op; ++ uint8_t soft; ++ uint8_t hard; ++}; ++ ++static char *get_name(__u32 idx) ++{ ++ char *filename, *name, *pos; ++ ++ filename = g_strdup_printf("/sys/class/rfkill/rfkill%u/name", idx); ++ if (g_file_get_contents(filename, &name, NULL, NULL) == FALSE) { ++ g_free(filename); ++ return NULL; ++ } ++ ++ g_free(filename); ++ ++ pos = strchr(name, '\n'); ++ if (pos) ++ *pos = '\0'; ++ ++ return name; ++} ++ ++static gboolean rfkill_event(GIOChannel *chan, ++ GIOCondition cond, gpointer data) ++{ ++ unsigned char buf[32]; ++ struct rfkill_event *event = (void *) buf; ++ char *sysname; ++ gboolean blocked; ++ gsize len; ++ GIOError err; ++ ++ if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) ++ return FALSE; ++ ++ memset(buf, 0, sizeof(buf)); ++ ++ err = g_io_channel_read(chan, (gchar *) buf, sizeof(buf), &len); ++ if (err) { ++ if (err == G_IO_ERROR_AGAIN) ++ return TRUE; ++ return FALSE; ++ } ++ ++ if (len != sizeof(struct rfkill_event)) ++ return TRUE; ++ ++ debug("idx %u type %u op %u soft %u hard %u", ++ event->idx, event->type, event->op, ++ event->soft, event->hard); ++ ++ blocked = (event->soft || event->hard) ? TRUE : FALSE; ++ /* We already disable devices correctly when rfkilled */ ++ if (blocked) ++ return TRUE; ++ ++ sysname = get_name(event->idx); ++ if (sysname == NULL) ++ return TRUE; ++ if (g_str_has_prefix(sysname, "hci") == FALSE) { ++ debug("Ignoring unblocked killswitch '%s'", sysname); ++ g_free(sysname); ++ return TRUE; ++ } ++ ++ switch (event->type) { ++ case RFKILL_TYPE_ALL: ++ case RFKILL_TYPE_BLUETOOTH: { ++ struct btd_adapter *adapter; ++ int id; ++ ++ id = atoi(sysname + strlen("hci")); ++ adapter = manager_find_adapter_by_id(id); ++ if (adapter) ++ adapter_set_powered(adapter, TRUE); ++ break; ++ } ++ default: ++ break; ++ } ++ ++ g_free(sysname); ++ ++ return TRUE; ++} ++ ++static GIOChannel *channel = NULL; ++ ++static int rfkill_init(void) ++{ ++ int fd; ++ ++ debug("Init rfkill plugin"); ++ ++ if (main_opts.remember_powered == FALSE) ++ return 0; ++ ++ fd = open("/dev/rfkill", O_RDWR); ++ if (fd < 0) { ++ debug("No rfkill support in the kernel"); ++ return -EIO; ++ } ++ ++ channel = g_io_channel_unix_new(fd); ++ g_io_channel_set_close_on_unref(channel, TRUE); ++ ++ g_io_add_watch(channel, G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR, ++ rfkill_event, NULL); ++ ++ return 0; ++} ++ ++static void rfkill_exit(void) ++{ ++ debug("Cleanup rfkill plugin"); ++ ++ if (channel == NULL) ++ return; ++ ++ g_io_channel_shutdown(channel, TRUE, NULL); ++ g_io_channel_unref(channel); ++ ++ channel = NULL; ++} ++ ++BLUETOOTH_PLUGIN_DEFINE(rfkill, VERSION, ++ BLUETOOTH_PLUGIN_PRIORITY_DEFAULT, rfkill_init, rfkill_exit) +diff --git a/src/adapter.c b/src/adapter.c +index 06640e7..06c3018 100644 +--- a/src/adapter.c ++++ b/src/adapter.c +@@ -483,21 +483,30 @@ done: + return 0; + } + +-static DBusMessage *set_powered(DBusConnection *conn, DBusMessage *msg, +- gboolean powered, void *data) ++int adapter_set_powered(struct btd_adapter *adapter, gboolean powered) + { +- struct btd_adapter *adapter = data; + uint8_t mode; +- int err; + + mode = powered ? get_mode(&adapter->bdaddr, "on") : MODE_OFF; + + if (mode == adapter->mode) +- return dbus_message_new_method_return(msg); ++ return -EALREADY; + +- err = set_mode(adapter, mode); +- if (err < 0) ++ return set_mode(adapter, mode); ++} ++ ++static DBusMessage *set_powered(DBusConnection *conn, DBusMessage *msg, ++ gboolean powered, void *data) ++{ ++ struct btd_adapter *adapter = data; ++ int err; ++ ++ err = adapter_set_powered(adapter, powered); ++ if (err < 0) { ++ if (err == -EALREADY) ++ return dbus_message_new_method_return(msg); + return failed_strerror(msg, -err); ++ } + + return dbus_message_new_method_return(msg); + } +diff --git a/src/adapter.h b/src/adapter.h +index d34fb80..fa02d5d 100644 +--- a/src/adapter.h ++++ b/src/adapter.h +@@ -110,6 +110,7 @@ void adapter_get_address(struct btd_adapter *adapter, bdaddr_t *bdaddr); + void adapter_set_state(struct btd_adapter *adapter, int state); + int adapter_get_state(struct btd_adapter *adapter); + gboolean adapter_is_ready(struct btd_adapter *adapter); ++int adapter_set_powered(struct btd_adapter *adapter, gboolean powered); + struct remote_dev_info *adapter_search_found_devices(struct btd_adapter *adapter, + struct remote_dev_info *match); + void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr, +-- +1.6.2.5 + diff --git a/bluez.spec b/bluez.spec index b174887..3926a78 100644 --- a/bluez.spec +++ b/bluez.spec @@ -1,7 +1,7 @@ Summary: Bluetooth utilities Name: bluez Version: 4.46 -Release: 2%{?dist} +Release: 3%{?dist} License: GPLv2+ Group: Applications/System Source: http://www.kernel.org/pub/linux/bluetooth/%{name}-%{version}.tar.gz @@ -24,6 +24,8 @@ Patch3: bluez-activate-wacom-mode2.patch Patch4: bluez-socket-mobile-cf-connection-kit.patch # http://thread.gmane.org/gmane.linux.bluez.kernel/2396 Patch5: 0001-Add-sixaxis-cable-pairing-plugin.patch +# http://thread.gmane.org/gmane.linux.bluez.kernel/2981 +Patch6: 0001-Add-rfkill-plugin.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root URL: http://www.bluez.org/ @@ -130,6 +132,7 @@ This includes hidd, dund and pand. %patch3 -p1 -b .wacom %patch4 -p1 -b .socket-mobile %patch5 -p1 -b .cable-pairing +%patch6 -p1 -b .rfkill %build libtoolize -f -c @@ -270,6 +273,10 @@ fi %config(noreplace) %{_sysconfdir}/sysconfig/pand %changelog +* Wed Jul 29 2009 Bastien Nocera 4.46-3 +- Add rfkill plugin to restore the state of the adapters + after coming back from a blocked adapter + * Fri Jul 24 2009 Fedora Release Engineering - 4.46-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild