gboolean audio_device_is_active(struct audio_device *dev, const char *interface) { if (!interface) { if ((dev->sink || dev->source) && avdtp_is_connected(&dev->src, &dev->dst)) return TRUE; if (dev->headset && headset_is_active(dev)) return TRUE; } else if (!strcmp(interface, AUDIO_SINK_INTERFACE) && dev->sink && avdtp_is_connected(&dev->src, &dev->dst)) return TRUE; else if (!strcmp(interface, AUDIO_SOURCE_INTERFACE) && dev->source && avdtp_is_connected(&dev->src, &dev->dst)) return TRUE; else if (!strcmp(interface, AUDIO_HEADSET_INTERFACE) && dev->headset && headset_is_active(dev)) return TRUE; else if (!strcmp(interface, AUDIO_CONTROL_INTERFACE) && dev->control && control_is_active(dev)) return TRUE; else if (!strcmp(interface, AUDIO_GATEWAY_INTERFACE) && dev->gateway && gateway_is_connected(dev)) return TRUE; return FALSE; }
static service_type_t select_service(struct audio_device *dev, const char *interface) { if (!interface) { if (dev->sink && avdtp_is_connected(&dev->src, &dev->dst)) return TYPE_SINK; else if (dev->source && avdtp_is_connected(&dev->src, &dev->dst)) return TYPE_SOURCE; else if (dev->headset && headset_is_active(dev)) return TYPE_HEADSET; else if (dev->sink) return TYPE_SINK; else if (dev->source) return TYPE_SOURCE; else if (dev->headset) return TYPE_HEADSET; } else if (!strcmp(interface, AUDIO_SOURCE_INTERFACE) && dev->source) return TYPE_SOURCE; else if (!strcmp(interface, AUDIO_SINK_INTERFACE) && dev->sink) return TYPE_SINK; else if (!strcmp(interface, AUDIO_HEADSET_INTERFACE) && dev->headset) return TYPE_HEADSET; else if (!strcmp(interface, AUDIO_GATEWAY_INTERFACE) && dev->gateway) return TYPE_GATEWAY; return TYPE_NONE; }
gboolean device_is_connected(struct audio_device *dev, const char *interface) { #ifndef BT_ALT_STACK if (!interface) { if ((dev->sink || dev->source) && avdtp_is_connected(&dev->src, &dev->dst)) return TRUE; if (dev->headset && headset_is_active(dev)) return TRUE; } else if (!strcmp(interface, AUDIO_SINK_INTERFACE) && dev->sink && avdtp_is_connected(&dev->src, &dev->dst)) return TRUE; else if (!strcmp(interface, AUDIO_SOURCE_INTERFACE) && dev->source && avdtp_is_connected(&dev->src, &dev->dst)) return TRUE; else if (!strcmp(interface, AUDIO_HEADSET_INTERFACE) && dev->headset && headset_is_active(dev)) return TRUE; else if (!strcmp(interface, AUDIO_CONTROL_INTERFACE) && dev->headset && control_is_active(dev)) return TRUE; #endif return FALSE; }
gboolean audio_device_is_active(struct audio_device *dev, const char *interface) { if (!interface) { if ((dev->sink || dev->source) && avdtp_is_connected(dev)) return TRUE; } else if (!strcmp(interface, AUDIO_SINK_INTERFACE) && dev->sink && avdtp_is_connected(dev)) return TRUE; else if (!strcmp(interface, AUDIO_SOURCE_INTERFACE) && dev->source && avdtp_is_connected(dev)) return TRUE; else if (!strcmp(interface, AUDIO_CONTROL_INTERFACE) && dev->control && control_is_active(dev)) return TRUE; return FALSE; }
static void avctp_server_cb(GIOChannel *chan, int err, const bdaddr_t *src, const bdaddr_t *dst, gpointer data) { socklen_t size; struct l2cap_options l2o; struct avctp *session; GIOCondition flags = G_IO_ERR | G_IO_HUP | G_IO_NVAL; struct audio_device *dev; char address[18]; if (err < 0) { error("AVCTP server socket: %s (%d)", strerror(-err), -err); return; } session = avctp_get(src, dst); if (!session) { error("Unable to create new AVCTP session"); goto drop; } if (session->sock >= 0) { error("Refusing unexpected connect from %s", address); goto drop; } dev = manager_find_device(&session->dst, AUDIO_CONTROL_INTERFACE, FALSE); if (!dev) { error("Unable to get audio device object for %s", address); goto drop; } if (!dev->control) dev->control = control_init(dev); device_remove_control_timer(dev); session->state = AVCTP_STATE_CONNECTING; session->sock = g_io_channel_unix_get_fd(chan); memset(&l2o, 0, sizeof(l2o)); size = sizeof(l2o); if (getsockopt(session->sock, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &size) < 0) { err = errno; error("getsockopt(L2CAP_OPTIONS): %s (%d)", strerror(err), err); avctp_unref(session); goto drop; } session->mtu = l2o.imtu; if (session->io) g_source_remove(session->io); session->io = g_io_add_watch(chan, flags, (GIOFunc) session_cb, session); g_io_channel_unref(chan); if (avdtp_is_connected(src, dst)) goto proceed; if (service_req_auth(src, dst, AVRCP_TARGET_UUID, auth_cb, session) < 0) goto drop; return; proceed: avctp_connect_session(session); return; drop: close(session->sock); }