{
struct btd_profile *profile = a;
struct btd_device *dev = b;
+ struct btd_service *service;
+ GSList *l;
- if (!profile->disconnect)
- return;
-
- profile->disconnect(dev, profile);
+ l = find_service_with_profile(dev->services, profile);
+ service = l->data;
+ btd_service_disconnect(service);
}
void device_request_disconnect(struct btd_device *device, DBusMessage *msg)
static int connect_next(struct btd_device *dev)
{
struct btd_profile *profile;
+ struct btd_service *service;
int err = -ENOENT;
while (dev->pending) {
+ GSList *l;
+
profile = dev->pending->data;
- err = profile->connect(dev, profile);
- if (err == 0)
+ l = find_service_with_profile(dev->services, profile);
+ service = l->data;
+
+ if (btd_service_connect(service) == 0)
return 0;
- error("Failed to connect %s: %s", profile->name,
- strerror(-err));
dev->pending = g_slist_remove(dev->pending, profile);
}
{
struct btd_device *dev = user_data;
struct btd_profile *p;
+ struct btd_service *service;
+ GSList *l;
const char *pattern;
char *uuid;
int err;
if (!p)
return btd_error_invalid_args(msg);
- if (!p->disconnect)
- return btd_error_not_supported(msg);
+ l = find_service_with_profile(dev->services, p);
+ service = l->data;
- err = p->disconnect(dev, p);
- if (err < 0)
- return btd_error_failed(msg, strerror(-err));
+ err = btd_service_disconnect(service);
+ if (err == 0) {
+ dev->disconnect = dbus_message_ref(msg);
+ return NULL;
+ }
- dev->disconnect = dbus_message_ref(msg);
+ if (err == -ENOTSUP)
+ return btd_error_not_supported(msg);
- return NULL;
+ return btd_error_failed(msg, strerror(-err));
}
static void device_svc_resolved(struct btd_device *dev, int err)
service->profile = NULL;
}
+int btd_service_connect(struct btd_service *service)
+{
+ struct btd_profile *profile = service->profile;
+ char addr[18];
+ int err;
+
+ if (!profile->connect)
+ return -ENOTSUP;
+
+ err = profile->connect(service->device, service->profile);
+ if (err == 0)
+ return 0;
+
+ ba2str(device_get_address(service->device), addr);
+ error("%s profile connect failed for %s: %s", profile->name, addr,
+ strerror(-err));
+
+ return err;
+}
+
+int btd_service_disconnect(struct btd_service *service)
+{
+ struct btd_profile *profile = service->profile;
+ char addr[18];
+ int err;
+
+ if (!profile->disconnect)
+ return -ENOTSUP;
+
+ err = profile->disconnect(service->device, service->profile);
+ if (err == 0)
+ return 0;
+
+ ba2str(device_get_address(service->device), addr);
+ error("%s profile disconnect failed for %s: %s", profile->name, addr,
+ strerror(-err));
+
+ return err;
+}
+
struct btd_device *btd_service_get_device(const struct btd_service *service)
{
return service->device;
int service_probe(struct btd_service *service);
void service_shutdown(struct btd_service *service);
+/* Connection control API */
+int btd_service_connect(struct btd_service *service);
+int btd_service_disconnect(struct btd_service *service);
+
/* Public member access */
struct btd_device *btd_service_get_device(const struct btd_service *service);
struct btd_profile *btd_service_get_profile(const struct btd_service *service);