static DBusMessage *dev_disconnect(DBusConnection *conn, DBusMessage *msg, void *data) { struct audio_device *dev = data; struct dev_priv *priv = dev->priv; if (priv->state == AUDIO_STATE_DISCONNECTED) return btd_error_not_connected(msg); if (priv->dc_req) return dbus_message_new_method_return(msg); priv->dc_req = dbus_message_ref(msg); if (dev->control) { device_remove_control_timer(dev); avrcp_disconnect(dev); } if (dev->sink && priv->sink_state != SINK_STATE_DISCONNECTED) sink_shutdown(dev->sink); else if (priv->hs_state != HEADSET_STATE_DISCONNECTED) headset_shutdown(dev); else { dbus_message_unref(priv->dc_req); priv->dc_req = NULL; return dbus_message_new_method_return(msg); } return NULL; }
static DBusMessage *sink_disconnect(DBusConnection *conn, DBusMessage *msg, void *data) { struct audio_device *device = data; struct sink *sink = device->sink; struct pending_request *pending; int err; if (!sink->session) return btd_error_not_connected(msg); if (sink->connect || sink->disconnect) return btd_error_busy(msg); if (sink->stream_state < AVDTP_STATE_OPEN) { DBusMessage *reply = dbus_message_new_method_return(msg); if (!reply) return NULL; avdtp_unref(sink->session); sink->session = NULL; return reply; } err = avdtp_close(sink->session, sink->stream, FALSE); if (err < 0) return btd_error_failed(msg, strerror(-err)); pending = g_new0(struct pending_request, 1); pending->conn = dbus_connection_ref(conn); pending->msg = dbus_message_ref(msg); sink->disconnect = pending; return NULL; }
static DBusMessage *port_disconnect(DBusConnection *conn, DBusMessage *msg, void *user_data) { struct serial_device *device = user_data; struct serial_port *port; const char *dev, *owner, *caller; if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &dev, DBUS_TYPE_INVALID) == FALSE) return NULL; port = find_port(device->ports, dev); if (!port) return btd_error_does_not_exist(msg); if (!port->listener_id) return btd_error_not_connected(msg); owner = dbus_message_get_sender(port->msg); caller = dbus_message_get_sender(msg); if (!g_str_equal(owner, caller)) return btd_error_not_authorized(msg); port_release(port); g_dbus_remove_watch(conn, port->listener_id); port->listener_id = 0; return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); }
static DBusMessage *disconnect_device(DBusConnection *conn, DBusMessage *msg, void *data) { DBusMessage *reply; struct network_server *ns = data; struct network_session *session; const char *addr, *devname; bdaddr_t dst_addr; if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &addr, DBUS_TYPE_STRING, &devname, DBUS_TYPE_INVALID)) return NULL; str2ba(addr, &dst_addr); session = find_session_by_addr(ns->sessions, dst_addr); if (!session) return btd_error_failed(msg, "No active session"); if (session->io) { bnep_if_down(devname); bnep_kill_connection(&dst_addr); } else return btd_error_not_connected(msg); reply = dbus_message_new_method_return(msg); if (!reply) return NULL; return reply; }
static DBusMessage *connection_disconnect(DBusConnection *conn, DBusMessage *msg, void *data) { struct network_peer *peer = data; GSList *l; for (l = peer->connections; l; l = l->next) { struct network_conn *nc = l->data; if (nc->state == DISCONNECTED) continue; return connection_cancel(conn, msg, nc); } return btd_error_not_connected(msg); }
static DBusMessage *key_pressed(DBusConnection *conn, DBusMessage *msg, uint8_t op, void *data) { struct control *control = data; int err; if (!control->session) return btd_error_not_connected(msg); if (!control->target) return btd_error_not_supported(msg); err = avctp_send_passthrough(control->session, op); if (err < 0) return btd_error_failed(msg, strerror(-err)); return dbus_message_new_method_return(msg); }
static DBusMessage *volume_down(DBusConnection *conn, DBusMessage *msg, void *data) { struct audio_device *device = data; struct control *control = device->control; int err; if (!control->session) return btd_error_not_connected(msg); if (!control->target) return btd_error_not_supported(msg); err = avctp_send_passthrough(control->session, VOL_DOWN_OP); if (err < 0) return btd_error_failed(msg, strerror(-err)); return dbus_message_new_method_return(msg); }
static DBusMessage *ag_disconnect(DBusConnection *conn, DBusMessage *msg, void *data) { struct audio_device *device = data; struct gateway *gw = device->gateway; DBusMessage *reply = NULL; char gw_addr[18]; if (!gw->rfcomm) return btd_error_not_connected(msg); reply = dbus_message_new_method_return(msg); if (!reply) return NULL; gateway_close(device); ba2str(&device->dst, gw_addr); DBG("Disconnected from %s, %s", gw_addr, device->path); return reply; }
static DBusMessage *local_disconnect(DBusConnection *conn, DBusMessage *msg, void *data) { struct network_peer *peer = data; GSList *l; for (l = peer->connections; l; l = l->next) { struct network_conn *nc = l->data; int err; if (nc->state == DISCONNECTED) continue; err = connection_disconnect(nc->service); if (err < 0) return btd_error_failed(msg, strerror(-err)); return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); } return btd_error_not_connected(msg); }