diff --git a/src/adapter.c b/src/adapter.c
index 0650271..a06c894 100644
--- a/src/adapter.c
+++ b/src/adapter.c
struct btd_adapter {
uint16_t dev_id;
- gboolean powered;
+
+ uint32_t current_settings;
+ uint32_t supported_settings;
+
char *path; /* adapter object path */
bdaddr_t bdaddr; /* adapter Bluetooth Address */
uint32_t dev_class; /* current class of device */
guint auto_timeout_id; /* Automatic connections timeout */
sdp_list_t *services; /* Services associated to adapter */
- bool connectable; /* connectable state */
bool toggle_discoverable; /* discoverable needs to be changed */
- gboolean discoverable; /* discoverable state */
- gboolean pairable; /* pairable state */
gboolean initialized;
gboolean off_requested; /* DEVDOWN ioctl was called */
if (adapter->discov_timeout > 0)
discov = FALSE;
else
- discov = adapter->discoverable;
+ discov = mgmt_discoverable(adapter->current_settings);
g_key_file_set_boolean(key_file, "General", "Discoverable", discov);
{
int err;
- if (adapter->powered == powered) {
+ if (mgmt_powered(adapter->current_settings) == powered) {
g_dbus_pending_property_success(id);
return;
}
static void set_pairable(struct btd_adapter *adapter, gboolean pairable,
bool reply, GDBusPendingPropertySet id)
{
- if (pairable == adapter->pairable)
+ if (pairable == mgmt_pairable(adapter->current_settings))
goto done;
mgmt_set_pairable(adapter->dev_id, pairable);
adapter);
}
-void adapter_update_pairable(struct btd_adapter *adapter, bool pairable)
-{
- if (adapter->pairable == pairable)
- return;
-
- adapter->pairable = pairable;
-
- store_adapter_info(adapter);
-
- g_dbus_emit_property_changed(btd_get_dbus_connection(), adapter->path,
- ADAPTER_INTERFACE, "Pairable");
-
- if (pairable && adapter->pairable_timeout)
- adapter_set_pairable_timeout(adapter,
- adapter->pairable_timeout);
-}
-
static struct session_req *find_session(GSList *list, const char *sender)
{
for (; list; list = list->next) {
return;
}
- if (adapter->powered)
+ if (mgmt_powered(adapter->current_settings))
mgmt_stop_discovery(adapter->dev_id);
else
discovery_cleanup(adapter);
return;
}
- if (adapter->discoverable)
+ if (mgmt_discoverable(adapter->current_settings))
mgmt_set_discoverable(adapter->dev_id, TRUE, timeout);
adapter->discov_timeout = timeout;
return;
}
- if (adapter->pairable)
+ if (mgmt_pairable(adapter->current_settings))
adapter_set_pairable_timeout(adapter, timeout);
adapter->pairable_timeout = timeout;
const char *sender = dbus_message_get_sender(msg);
int err;
- if (!adapter->powered)
+ if (!mgmt_powered(adapter->current_settings))
return btd_error_not_ready(msg);
req = find_session(adapter->disc_sessions, sender);
struct session_req *req;
const char *sender = dbus_message_get_sender(msg);
- if (!adapter->powered)
+ if (!mgmt_powered(adapter->current_settings))
return btd_error_not_ready(msg);
req = find_session(adapter->disc_sessions, sender);
{
struct btd_adapter *adapter = data;
dbus_bool_t value;
+ bool powered = mgmt_powered(adapter->current_settings);
- value = (adapter->powered && !adapter->off_requested) ? TRUE : FALSE;
+ value = (powered && !adapter->off_requested) ? TRUE : FALSE;
dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &value);
return TRUE;
struct btd_adapter *adapter = data;
dbus_bool_t value;
- value = adapter->discoverable ? TRUE : FALSE;
+ value = mgmt_discoverable(adapter->current_settings) ? TRUE : FALSE;
dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &value);
return TRUE;
DBusMessageIter *iter, void *data)
{
struct btd_adapter *adapter = data;
+ dbus_bool_t pairable = mgmt_pairable(adapter->current_settings);
- dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN,
- &adapter->pairable);
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &pairable);
return TRUE;
}
bool btd_adapter_get_pairable(struct btd_adapter *adapter)
{
- return adapter->pairable;
+ return mgmt_pairable(adapter->current_settings);
}
uint32_t btd_adapter_get_class(struct btd_adapter *adapter)
DBG("%s added to %s's connect_list", device_get_path(device),
adapter->name);
- if (!adapter->powered)
+ if (!mgmt_powered(adapter->current_settings))
return;
if (adapter->off_requested)
btd_device_unref(device);
}
-void btd_adapter_start(struct btd_adapter *adapter)
+static void adapter_start(struct btd_adapter *adapter)
{
struct session_req *req;
adapter->off_requested = FALSE;
- adapter->powered = TRUE;
g_dbus_emit_property_changed(btd_get_dbus_connection(), adapter->path,
ADAPTER_INTERFACE, "Powered");
adapter->profiles = NULL;
}
-int btd_adapter_stop(struct btd_adapter *adapter)
+static int adapter_stop(struct btd_adapter *adapter)
{
DBusConnection *conn = btd_get_dbus_connection();
bool emit_discovering = false;
/* check pending requests */
reply_pending_requests(adapter);
- adapter->powered = FALSE;
-
if (adapter->discovery) {
emit_discovering = true;
stop_discovery(adapter);
adapter_remove_connection(adapter, device);
}
- adapter->connectable = false;
-
adapter->off_requested = FALSE;
if (emit_discovering)
return 0;
}
+static void adapter_pairable_changed(struct btd_adapter *adapter,
+ uint32_t new_settings)
+{
+ g_dbus_emit_property_changed(btd_get_dbus_connection(), adapter->path,
+ ADAPTER_INTERFACE, "Pairable");
+
+ if (mgmt_pairable(new_settings) && adapter->pairable_timeout)
+ adapter_set_pairable_timeout(adapter,
+ adapter->pairable_timeout);
+}
+
+static void adapter_connectable_changed(struct btd_adapter *adapter,
+ uint32_t new_settings)
+{
+ if (adapter->toggle_discoverable) {
+ bool discov = mgmt_discoverable(adapter->current_settings);
+ DBG("toggling discoverable from %u to %u", discov, !discov);
+ mgmt_set_discoverable(adapter->dev_id, !discov,
+ adapter->discov_timeout);
+ adapter->toggle_discoverable = false;
+ }
+}
+
+static void adapter_discoverable_changed(struct btd_adapter *adapter,
+ uint32_t new_settings)
+{
+ struct DBusConnection *conn = btd_get_dbus_connection();
+
+ g_dbus_emit_property_changed(conn, adapter->path, ADAPTER_INTERFACE,
+ "Discoverable");
+}
+
+static void adapter_powered_changed(struct btd_adapter *adapter,
+ uint32_t new_settings)
+{
+ if (mgmt_powered(new_settings))
+ adapter_start(adapter);
+ else
+ adapter_stop(adapter);
+}
+
+void adapter_update_settings(struct btd_adapter *adapter,
+ uint32_t new_settings)
+{
+ bool store_info = false;
+
+ if (adapter->current_settings == new_settings)
+ return;
+
+ if (mgmt_pairable(new_settings) !=
+ mgmt_pairable(adapter->current_settings))
+ adapter_pairable_changed(adapter, new_settings);
+
+ if (mgmt_connectable(new_settings) !=
+ mgmt_connectable(adapter->current_settings))
+ adapter_connectable_changed(adapter, new_settings);
+
+ if (mgmt_discoverable(new_settings) !=
+ mgmt_discoverable(adapter->current_settings)) {
+ adapter_discoverable_changed(adapter, new_settings);
+ store_info = true;
+ }
+
+ if (mgmt_powered(new_settings) !=
+ mgmt_powered(adapter->current_settings))
+ adapter_powered_changed(adapter, new_settings);
+
+ adapter->current_settings = new_settings;
+
+ if (store_info)
+ store_adapter_info(adapter);
+}
+
static void free_service_auth(gpointer data, gpointer user_data)
{
struct service_auth *auth = data;
gerr = NULL;
}
- if (!adapter->connectable)
+ if (!mgmt_connectable(adapter->current_settings))
mgmt_set_connectable(adapter->dev_id, TRUE);
- if (adapter->discov_timeout > 0 && adapter->discoverable) {
- if (adapter->connectable)
+ if (adapter->discov_timeout > 0 &&
+ mgmt_discoverable(adapter->current_settings)) {
+ if (mgmt_connectable(adapter->current_settings))
mgmt_set_discoverable(adapter->dev_id, FALSE, 0);
else
adapter->toggle_discoverable = true;
- } else if (stored_discoverable != adapter->discoverable) {
- if (adapter->connectable)
+ } else if (stored_discoverable !=
+ mgmt_discoverable(adapter->current_settings)) {
+ if (mgmt_connectable(adapter->current_settings))
mgmt_set_discoverable(adapter->dev_id,
stored_discoverable,
adapter->discov_timeout);
g_key_file_free(key_file);
}
-static gboolean adapter_setup(struct btd_adapter *adapter, uint32_t settings)
+static gboolean adapter_setup(struct btd_adapter *adapter,
+ uint32_t current_settings,
+ uint32_t supported_settings)
{
struct agent *agent;
- adapter->powered = mgmt_powered(settings);
- adapter->connectable = mgmt_connectable(settings);
- adapter->discoverable = mgmt_discoverable(settings);
- adapter->pairable = mgmt_pairable(settings);
+ adapter->current_settings = current_settings;
+ adapter->supported_settings = supported_settings;
if (bacmp(&adapter->bdaddr, BDADDR_ANY) == 0) {
error("No address available for hci%d", adapter->dev_id);
g_slist_free(adapter->pin_callbacks);
- if (adapter->powered)
+ if (mgmt_powered(adapter->current_settings))
mgmt_set_powered(adapter->dev_id, FALSE);
}
}
}
-void adapter_update_connectable(struct btd_adapter *adapter, bool connectable)
-{
- if (adapter->connectable == connectable)
- return;
-
- if (adapter->toggle_discoverable) {
- DBG("toggling discoverable from %u to %u",
- adapter->discoverable, !adapter->discoverable);
- mgmt_set_discoverable(adapter->dev_id, !adapter->discoverable,
- adapter->discov_timeout);
- adapter->toggle_discoverable = false;
- }
-
- adapter->connectable = connectable;
-}
-
-void adapter_update_discoverable(struct btd_adapter *adapter,
- bool discoverable)
-{
- struct DBusConnection *conn = btd_get_dbus_connection();
-
- if (adapter->discoverable == discoverable)
- return;
-
- adapter->discoverable = discoverable;
- g_dbus_emit_property_changed(conn, adapter->path, ADAPTER_INTERFACE,
- "Discoverable");
-
- store_adapter_info(adapter);
-}
-
struct agent *adapter_get_agent(struct btd_adapter *adapter)
{
return agent_get(NULL);
int btd_adapter_restore_powered(struct btd_adapter *adapter)
{
- if (adapter->powered)
+ if (mgmt_powered(adapter->current_settings))
return 0;
return mgmt_set_powered(adapter->dev_id, TRUE);
int btd_adapter_set_fast_connectable(struct btd_adapter *adapter,
gboolean enable)
{
- if (!adapter->powered)
+ if (!mgmt_powered(adapter->current_settings))
return -EINVAL;
return mgmt_set_fast_connectable(adapter->dev_id, enable);
int which, int timeout, uint32_t *clock,
uint16_t *accuracy)
{
- if (!adapter->powered)
+ if (!mgmt_powered(adapter->current_settings))
return -EINVAL;
return mgmt_read_clock(adapter->dev_id, bdaddr, which,
}
static struct btd_adapter *adapter_register(int id, const bdaddr_t *bdaddr,
- uint32_t settings)
+ uint32_t current_settings,
+ uint32_t supported_settings)
{
struct btd_adapter *adapter;
adapters = g_slist_append(adapters, adapter);
- if (!adapter_setup(adapter, settings)) {
+ if (!adapter_setup(adapter, current_settings, supported_settings)) {
adapters = g_slist_remove(adapters, adapter);
btd_adapter_unref(adapter);
return NULL;
return;
}
- adapter = adapter_register(index, &rp->bdaddr, rp->current_settings);
+ adapter = adapter_register(index, &rp->bdaddr, rp->current_settings,
+ rp->supported_settings);
if (adapter == NULL) {
error("Unable to register new adapter");
return;
set_dev_class(adapter, adapter->major_class, adapter->minor_class);
if (mgmt_powered(rp->current_settings))
- btd_adapter_start(adapter);
+ adapter_start(adapter);
btd_adapter_unref(adapter);
}
diff --git a/src/adapter.h b/src/adapter.h
index de4eda5..2462e31 100644
--- a/src/adapter.h
+++ b/src/adapter.h
struct btd_adapter *adapter_get_default(void);
void adapter_foreach(adapter_cb func, gpointer user_data);
-void btd_adapter_start(struct btd_adapter *adapter);
-
-int btd_adapter_stop(struct btd_adapter *adapter);
-
bool btd_adapter_get_pairable(struct btd_adapter *adapter);
uint32_t btd_adapter_get_class(struct btd_adapter *adapter);
uint8_t bdaddr_type, int8_t rssi,
bool confirm_name, bool legacy,
uint8_t *data, uint8_t data_len);
-void adapter_update_connectable(struct btd_adapter *adapter, bool connectable);
-void adapter_update_discoverable(struct btd_adapter *adapter,
- bool discoverable);
+void adapter_update_settings(struct btd_adapter *adapter,
+ uint32_t new_settings);
int adapter_set_name(struct btd_adapter *adapter, const char *name);
void adapter_name_changed(struct btd_adapter *adapter, const char *name);
void adapter_service_insert(struct btd_adapter *adapter, void *rec);
void adapter_service_remove(struct btd_adapter *adapter, void *rec);
void btd_adapter_class_changed(struct btd_adapter *adapter,
const uint8_t *new_class);
-void adapter_update_pairable(struct btd_adapter *adapter, bool pairable);
struct agent *adapter_get_agent(struct btd_adapter *adapter);
void adapter_add_connection(struct btd_adapter *adapter,
diff --git a/src/mgmt.c b/src/mgmt.c
index 449d947..14c17c3 100644
--- a/src/mgmt.c
+++ b/src/mgmt.c
return mgmt_set_mode(index, MGMT_OP_SET_LE, le);
}
-static void update_settings(struct btd_adapter *adapter, uint32_t settings)
-{
- DBG("new settings 0x%08x", settings);
-
- adapter_update_connectable(adapter, mgmt_connectable(settings));
- adapter_update_discoverable(adapter, mgmt_discoverable(settings));
- adapter_update_pairable(adapter, mgmt_pairable(settings));
-}
-
static void mgmt_update_powered(struct btd_adapter *adapter,
struct controller_info *info,
uint32_t settings)
{
if (!mgmt_powered(settings)) {
- btd_adapter_stop(adapter);
g_slist_free_full(info->pending_uuids, g_free);
info->pending_uuids = NULL;
info->pending_uuid = FALSE;
return;
}
- btd_adapter_start(adapter);
-
- update_settings(adapter, settings);
+ adapter_update_settings(adapter, settings);
}
static void mgmt_new_settings(uint16_t index, void *buf, size_t len)
if (new_power != old_power)
mgmt_update_powered(adapter, info, settings);
else
- update_settings(adapter, settings);
+ adapter_update_settings(adapter, settings);
info->current_settings = settings;
}