gboolean gateway_cancel_stream(struct audio_device *dev, unsigned int id) { struct gateway *gw = dev->gateway; GSList *l; struct connect_cb *cb = NULL; for (l = gw->callbacks; l != NULL; l = l->next) { struct connect_cb *tmp = l->data; if (tmp->id == id) { cb = tmp; break; } } if (!cb) return FALSE; gw->callbacks = g_slist_remove(gw->callbacks, cb); g_free(cb); gateway_suspend_stream(dev); return TRUE; }
static guint suspend_gateway(struct media_transport *transport, struct media_owner *owner) { struct audio_device *device = transport->device; static int id = 1; if (!owner) { gateway_unlock(device, GATEWAY_LOCK_READ | GATEWAY_LOCK_WRITE); transport->in_use = FALSE; return 0; } gateway_suspend_stream(device); g_idle_add(gateway_suspend_complete, owner); return id++; }
gboolean gateway_unlock(struct audio_device *dev, gateway_lock_t lock) { struct gateway *gw = dev->gateway; if (!(gw->lock & lock)) return FALSE; gw->lock &= ~lock; if (gw->lock) return TRUE; if (gw->state == GATEWAY_STATE_PLAYING) gateway_suspend_stream(dev); return TRUE; }
static void sco_connect_cb(GIOChannel *chan, GError *err, gpointer user_data) { struct audio_device *dev = (struct audio_device *) user_data; struct gateway *gw = dev->gateway; DBG("at the begin of sco_connect_cb() in gateway.c"); gw->sco = g_io_channel_ref(chan); gw->sco_id = g_io_add_watch(gw->sco, G_IO_ERR | G_IO_HUP | G_IO_NVAL, (GIOFunc) sco_io_cb, dev); if (err) { error("sco_connect_cb(): %s", err->message); gateway_suspend_stream(dev); return; } change_state(dev, GATEWAY_STATE_PLAYING); run_connect_cb(dev, NULL); }
static void start_suspend(struct audio_device *dev, struct unix_client *client) { struct a2dp_data *a2dp; struct headset_data *hs; unsigned int id; gboolean unref_avdtp_on_fail = FALSE; switch (client->type) { case TYPE_SINK: case TYPE_SOURCE: a2dp = &client->d.a2dp; if (!a2dp->session) { a2dp->session = avdtp_get(&dev->src, &dev->dst); unref_avdtp_on_fail = TRUE; } if (!a2dp->session) { error("Unable to get a session"); goto failed; } if (!a2dp->sep) { error("Unable to get a sep"); goto failed; } id = a2dp_suspend(a2dp->session, a2dp->sep, a2dp_suspend_complete, client); client->cancel = a2dp_cancel; break; case TYPE_HEADSET: hs = &client->d.hs; if (!hs->locked) { error("seid not opened"); goto failed; } id = headset_suspend_stream(dev, headset_suspend_complete, client); client->cancel = headset_cancel_stream; break; case TYPE_GATEWAY: gateway_suspend_stream(dev); client->cancel = gateway_cancel_stream; headset_suspend_complete(dev, client); id = 1; break; default: error("No known services for device"); goto failed; } if (id == 0) { error("suspend failed"); goto failed; } return; failed: if (unref_avdtp_on_fail && a2dp->session) { avdtp_unref(a2dp->session); a2dp->session = NULL; } unix_ipc_error(client, BT_STOP_STREAM, EIO); }