static gboolean mpeg_setconf_ind(struct avdtp *session, struct avdtp_local_sep *sep, struct avdtp_stream *stream, GSList *caps, uint8_t *err, uint8_t *category, void *user_data) { struct a2dp_sep *a2dp_sep = user_data; struct audio_device *dev; if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) debug("Sink %p: Set_Configuration_Ind", sep); else debug("Source %p: Set_Configuration_Ind", sep); dev = a2dp_get_dev(session); if (!dev) { *err = AVDTP_UNSUPPORTED_CONFIGURATION; *category = 0x00; return FALSE; } avdtp_stream_add_cb(session, stream, stream_state_changed, a2dp_sep); a2dp_sep->stream = stream; if (a2dp_sep->type == AVDTP_SEP_TYPE_SOURCE) sink_new_stream(dev, session, stream); return TRUE; }
static gboolean sbc_setconf_ind(struct avdtp *session, struct avdtp_local_sep *sep, struct avdtp_stream *stream, GSList *caps, uint8_t *err, uint8_t *category, void *user_data) { struct a2dp_sep *a2dp_sep = user_data; struct audio_device *dev; struct avdtp_service_capability *cap; struct avdtp_media_codec_capability *codec_cap; struct sbc_codec_cap *sbc_cap; if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) debug("Sink %p: Set_Configuration_Ind", sep); else debug("Source %p: Set_Configuration_Ind", sep); dev = a2dp_get_dev(session); if (!dev) { *err = AVDTP_UNSUPPORTED_CONFIGURATION; *category = 0x00; return FALSE; } /* Check bipool range */ for (codec_cap = NULL; caps; caps = g_slist_next(caps)) { cap = caps->data; if (cap->category != AVDTP_MEDIA_CODEC) continue; if (cap->length < sizeof(struct sbc_codec_cap)) continue; codec_cap = (void *) cap->data; if (codec_cap->media_codec_type != A2DP_CODEC_SBC) continue; sbc_cap = (void *) codec_cap; if (sbc_cap->min_bitpool < MIN_BITPOOL || sbc_cap->max_bitpool > MAX_BITPOOL) { *err = AVDTP_UNSUPPORTED_CONFIGURATION; *category = AVDTP_MEDIA_CODEC; return FALSE; } break; } avdtp_stream_add_cb(session, stream, stream_state_changed, a2dp_sep); a2dp_sep->stream = stream; if (a2dp_sep->type == AVDTP_SEP_TYPE_SOURCE) sink_new_stream(dev, session, stream); return TRUE; }
static struct a2dp_setup *setup_new(struct avdtp *session) { struct audio_device *dev; struct a2dp_setup *setup; dev = a2dp_get_dev(session); if (!dev) { error("Unable to create setup"); return NULL; } setup = g_new0(struct a2dp_setup, 1); setup->session = avdtp_ref(session); setup->dev = a2dp_get_dev(session); setups = g_slist_append(setups, setup); return setup; }
static struct a2dp_setup *find_setup_by_dev(struct audio_device *dev) { GSList *l; for (l = setups; l != NULL; l = l->next) { struct a2dp_setup *setup = l->data; struct audio_device *setup_dev = a2dp_get_dev(setup->session); if (setup_dev == dev) return setup; } return NULL; }
static gboolean delayreport_ind(struct avdtp *session, struct avdtp_local_sep *sep, uint8_t rseid, uint16_t delay, uint8_t *err, void *user_data) { struct a2dp_sep *a2dp_sep = user_data; struct audio_device *dev = a2dp_get_dev(session); if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) DBG("Sink %p: DelayReport_Ind", sep); else DBG("Source %p: DelayReport_Ind", sep); unix_delay_report(dev, rseid, delay); return TRUE; }
static void setconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep, struct avdtp_stream *stream, struct avdtp_error *err, void *user_data) { struct a2dp_sep *a2dp_sep = user_data; struct a2dp_setup *setup; struct audio_device *dev; int ret; if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) DBG("Sink %p: Set_Configuration_Cfm", sep); else DBG("Source %p: Set_Configuration_Cfm", sep); setup = find_setup_by_session(session); if (err) { if (setup) { setup->err = err; finalize_config(setup); } return; } avdtp_stream_add_cb(session, stream, stream_state_changed, a2dp_sep); a2dp_sep->stream = stream; if (!setup) return; dev = a2dp_get_dev(session); /* Notify D-Bus interface of the new stream */ if (a2dp_sep->type == AVDTP_SEP_TYPE_SOURCE) sink_new_stream(dev, session, setup->stream); else source_new_stream(dev, session, setup->stream); ret = avdtp_open(session, stream); if (ret < 0) { error("Error on avdtp_open %s (%d)", strerror(-ret), -ret); setup->stream = NULL; finalize_config_errno(setup, ret); } }
static gboolean mpeg_setconf_ind(struct avdtp *session, struct avdtp_local_sep *sep, struct avdtp_stream *stream, GSList *caps, uint8_t *err, uint8_t *category, void *user_data) { struct a2dp_sep *a2dp_sep = user_data; struct audio_device *dev; if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) DBG("Sink %p: Set_Configuration_Ind", sep); else DBG("Source %p: Set_Configuration_Ind", sep); dev = a2dp_get_dev(session); if (!dev) { *err = AVDTP_UNSUPPORTED_CONFIGURATION; *category = 0x00; return FALSE; } for (; caps != NULL; caps = g_slist_next(caps)) { struct avdtp_service_capability *cap = caps->data; if (cap->category == AVDTP_DELAY_REPORTING && !a2dp_sep->delay_reporting) { *err = AVDTP_UNSUPPORTED_CONFIGURATION; *category = AVDTP_DELAY_REPORTING; return FALSE; } } avdtp_stream_add_cb(session, stream, stream_state_changed, a2dp_sep); a2dp_sep->stream = stream; if (a2dp_sep->type == AVDTP_SEP_TYPE_SOURCE) sink_new_stream(dev, session, stream); return TRUE; }