@@ -250,6 +250,7 @@ struct btd_adapter {
uint32_t dev_class; /* controller class of device */
char *name; /* controller device name */
char *short_name; /* controller short name */
+ bool blocked; /* whether rfkill is enabled */
uint32_t supported_settings; /* controller supported settings */
uint32_t pending_settings; /* pending controller settings */
uint32_t current_settings; /* current controller settings */
@@ -654,6 +655,8 @@ static void set_mode_complete(uint8_t status, uint16_t length,
if (status != MGMT_STATUS_SUCCESS) {
btd_error(adapter->dev_id, "Failed to set mode: %s (0x%02x)",
mgmt_errstr(status), status);
+ if (status == MGMT_STATUS_RFKILLED)
+ adapter->blocked = true;
adapter->pending_settings &= ~data->setting;
return;
}
@@ -2914,10 +2917,12 @@ static void property_set_mode_complete(uint8_t status, uint16_t length,
btd_error(adapter->dev_id, "Failed to set mode: %s (0x%02x)",
mgmt_errstr(status), status);
- if (status == MGMT_STATUS_RFKILLED)
+ if (status == MGMT_STATUS_RFKILLED) {
dbus_err = ERROR_INTERFACE ".Blocked";
- else
+ adapter->blocked = true;
+ } else {
dbus_err = ERROR_INTERFACE ".Failed";
+ }
g_dbus_pending_property_error(data->id, dbus_err,
mgmt_errstr(status));
@@ -7548,6 +7553,12 @@ int btd_cancel_authorization(guint id)
int btd_adapter_restore_powered(struct btd_adapter *adapter)
{
+ if (adapter->blocked) {
+ adapter->blocked = false;
+ g_dbus_emit_property_changed(dbus_conn, adapter->path,
+ ADAPTER_INTERFACE, "PowerState");
+ }
+
if (btd_adapter_get_powered(adapter))
return 0;
@@ -7556,6 +7567,16 @@ int btd_adapter_restore_powered(struct btd_adapter *adapter)
return 0;
}
+int btd_adapter_set_blocked(struct btd_adapter *adapter)
+{
+ if (!adapter->blocked) {
+ adapter->blocked = true;
+ g_dbus_emit_property_changed(dbus_conn, adapter->path,
+ ADAPTER_INTERFACE, "PowerState");
+ }
+ return 0;
+}
+
void btd_adapter_register_pin_cb(struct btd_adapter *adapter,
btd_adapter_pin_cb_t cb)
{
@@ -143,6 +143,7 @@ guint btd_request_authorization_cable_configured(const bdaddr_t *src, const bdad
int btd_cancel_authorization(guint id);
int btd_adapter_restore_powered(struct btd_adapter *adapter);
+int btd_adapter_set_blocked(struct btd_adapter *adapter);
typedef ssize_t (*btd_adapter_pin_cb_t) (struct btd_adapter *adapter,
struct btd_device *dev, char *out, bool *display,
@@ -61,6 +61,7 @@ static gboolean rfkill_event(GIOChannel *chan,
struct rfkill_event event = { 0 };
struct btd_adapter *adapter;
char sysname[PATH_MAX];
+ bool blocked = false;
ssize_t len;
int fd, id;
@@ -84,7 +85,7 @@ static gboolean rfkill_event(GIOChannel *chan,
event.soft, event.hard);
if (event.soft || event.hard)
- return TRUE;
+ blocked = true;
if (event.op != RFKILL_OP_CHANGE)
return TRUE;
@@ -122,7 +123,10 @@ static gboolean rfkill_event(GIOChannel *chan,
DBG("RFKILL unblock for hci%d", id);
- btd_adapter_restore_powered(adapter);
+ if (blocked)
+ btd_adapter_set_blocked(adapter);
+ else
+ btd_adapter_restore_powered(adapter);
return TRUE;
}