?? a2dp.c
字號:
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 sink.c of the new stream */ sink_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 getconf_ind(struct avdtp *session, struct avdtp_local_sep *sep, uint8_t *err, void *user_data){ struct a2dp_sep *a2dp_sep = user_data; if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) debug("Sink %p: Get_Configuration_Ind"); else debug("Source %p: Get_Configuration_Ind"); return TRUE;}static void getconf_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; if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) debug("Sink %p: Set_Configuration_Cfm", sep); else debug("Source %p: Set_Configuration_Cfm", sep);}static gboolean open_ind(struct avdtp *session, struct avdtp_local_sep *sep, struct avdtp_stream *stream, uint8_t *err, void *user_data){ struct a2dp_sep *a2dp_sep = user_data; if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) debug("Sink %p: Open_Ind", sep); else debug("Source %p: Open_Ind", sep); return TRUE;}static void open_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; if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) debug("Sink %p: Open_Cfm", sep); else debug("Source %p: Open_Cfm", sep); setup = find_setup_by_session(session); if (!setup) return; if (setup->canceled) { if (!err) avdtp_close(session, stream); setup_unref(setup); return; } if (setup->reconfigure) setup->reconfigure = FALSE; if (err) { setup->stream = NULL; setup->err = err; finalize_config(setup); } else finalize_config_errno(setup, 0);}static gboolean suspend_timeout(struct a2dp_sep *sep){ if (avdtp_suspend(sep->session, sep->stream) == 0) sep->suspending = TRUE; sep->suspend_timer = 0; avdtp_unref(sep->session); sep->session = NULL; return FALSE;}static gboolean start_ind(struct avdtp *session, struct avdtp_local_sep *sep, struct avdtp_stream *stream, uint8_t *err, void *user_data){ struct a2dp_sep *a2dp_sep = user_data; if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) debug("Sink %p: Start_Ind", sep); else debug("Source %p: Start_Ind", sep); if (!a2dp_sep->locked) { a2dp_sep->session = avdtp_ref(session); a2dp_sep->suspend_timer = g_timeout_add(SUSPEND_TIMEOUT, (GSourceFunc) suspend_timeout, a2dp_sep); } return TRUE;}static void start_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; if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) debug("Sink %p: Start_Cfm", sep); else debug("Source %p: Start_Cfm", sep); setup = find_setup_by_session(session); if (!setup) return; if (setup->canceled) { if (!err) avdtp_close(session, stream); setup_unref(setup); return; } if (err) { setup->stream = NULL; setup->err = err; finalize_resume(setup); } else finalize_resume_errno(setup, 0);}static gboolean suspend_ind(struct avdtp *session, struct avdtp_local_sep *sep, struct avdtp_stream *stream, uint8_t *err, void *user_data){ struct a2dp_sep *a2dp_sep = user_data; if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) debug("Sink %p: Suspend_Ind", sep); else debug("Source %p: Suspend_Ind", sep); if (a2dp_sep->suspend_timer) { g_source_remove(a2dp_sep->suspend_timer); a2dp_sep->suspend_timer = 0; avdtp_unref(a2dp_sep->session); a2dp_sep->session = NULL; } return TRUE;}static void suspend_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; gboolean start; if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) debug("Sink %p: Suspend_Cfm", sep); else debug("Source %p: Suspend_Cfm", sep); a2dp_sep->suspending = FALSE; setup = find_setup_by_session(session); if (!setup) return; start = setup->start; setup->start = FALSE; if (err) { setup->stream = NULL; setup->err = err; finalize_suspend(setup); } else finalize_suspend_errno(setup, 0); if (!start) return; if (err) { setup->err = err; finalize_suspend(setup); } else if (avdtp_start(session, a2dp_sep->stream) < 0) { struct avdtp_error start_err; error("avdtp_start failed"); avdtp_error_init(&start_err, AVDTP_ERROR_ERRNO, EIO); setup->err = err; finalize_suspend(setup); }}static gboolean close_ind(struct avdtp *session, struct avdtp_local_sep *sep, struct avdtp_stream *stream, uint8_t *err, void *user_data){ struct a2dp_sep *a2dp_sep = user_data; if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) debug("Sink %p: Close_Ind", sep); else debug("Source %p: Close_Ind", sep); return TRUE;}static gboolean reconfigure(gpointer data){ struct a2dp_setup *setup = data; struct avdtp_local_sep *lsep; struct avdtp_remote_sep *rsep; int posix_err; posix_err = avdtp_get_seps(setup->session, AVDTP_SEP_TYPE_SINK, AVDTP_MEDIA_TYPE_AUDIO, A2DP_CODEC_SBC, &lsep, &rsep); if (posix_err < 0) { error("No matching ACP and INT SEPs found"); finalize_config_errno(setup, posix_err); } posix_err = avdtp_set_configuration(setup->session, rsep, lsep, setup->client_caps, &setup->stream); if (posix_err < 0) { error("avdtp_set_configuration: %s", strerror(-posix_err)); finalize_config_errno(setup, posix_err); } return FALSE;}static void close_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; if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) debug("Sink %p: Close_Cfm", sep); else debug("Source %p: Close_Cfm", sep); setup = find_setup_by_session(session); if (!setup) return; if (setup->canceled) { setup_unref(setup); return; } if (err) { setup->stream = NULL; setup->err = err; finalize_config(setup); return; } if (setup->reconfigure) g_timeout_add(RECONFIGURE_TIMEOUT, reconfigure, setup);}static gboolean abort_ind(struct avdtp *session, struct avdtp_local_sep *sep, struct avdtp_stream *stream, uint8_t *err, void *user_data){ struct a2dp_sep *a2dp_sep = user_data; if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) debug("Sink %p: Abort_Ind", sep); else debug("Source %p: Abort_Ind", sep); a2dp_sep->stream = NULL; return TRUE;}static void abort_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; if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) debug("Sink %p: Abort_Cfm", sep); else debug("Source %p: Abort_Cfm", sep); setup = find_setup_by_session(session); if (!setup) return; setup_unref(setup);}static gboolean reconf_ind(struct avdtp *session, struct avdtp_local_sep *sep, uint8_t *err, void *user_data){ struct a2dp_sep *a2dp_sep = user_data; if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) debug("Sink %p: ReConfigure_Ind", sep); else debug("Source %p: ReConfigure_Ind", sep); return TRUE;}static void reconf_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; if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) debug("Sink %p: ReConfigure_Cfm", sep); else debug("Source %p: ReConfigure_Cfm", sep); setup = find_setup_by_session(session); if (!setup) return; if (setup->canceled) { if (!err) avdtp_close(session, stream); setup_unref(setup); return; } if (err) { setup->stream = NULL; setup->err = err; finalize_config(setup); } else finalize_config_errno(setup, 0);}static struct avdtp_sep_cfm cfm = { .set_configuration = setconf_cfm, .get_configuration = getconf_cfm, .open = open_cfm, .start = start_cfm, .suspend = suspend_cfm, .close = close_cfm, .abort = abort_cfm, .reconfigure = reconf_cfm};static struct avdtp_sep_ind sbc_ind = { .get_capability = sbc_getcap_ind, .set_configuration = sbc_setconf_ind, .get_configuration = getconf_ind, .open = open_ind, .start = start_ind, .suspend = suspend_ind, .close = close_ind, .abort = abort_ind, .reconfigure = reconf_ind};static struct avdtp_sep_ind mpeg_ind = { .get_capability = mpeg_getcap_ind, .set_configuration = mpeg_setconf_ind, .get_configuration = getconf_ind, .open = open_ind, .start = start_ind, .suspend = suspend_ind, .close = close_ind, .abort = abort_ind, .reconfigure = reconf_ind};static int a2dp_source_record(sdp_buf_t *buf){ sdp_list_t *svclass_id, *pfseq, *apseq, *root; uuid_t root_uuid, l2cap, avdtp, a2src; sdp_profile_desc_t profile[1]; sdp_list_t *aproto, *proto[2]; sdp_record_t record; sdp_data_t *psm, *version, *features; uint16_t lp = AVDTP_UUID, ver = 0x0100, feat = 0x000F; int ret = 0; memset(&record, 0, sizeof(sdp_record_t)); sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); sdp_uuid16_create(&a2src, AUDIO_SOURCE_SVCLASS_ID); svclass_id = sdp_list_append(0, &a2src); sdp_set_service_classes(&record, svclass_id); sdp_uuid16_create(&profile[0].uuid, ADVANCED_AUDIO_PROFILE_ID); profile[0].version = 0x0100; pfseq = sdp_list_append(0, &profile[0]); sdp_set_profile_descs(&record, pfseq); sdp_uuid16_create(&l2cap, L2CAP_UUID); proto[0] = sdp_list_append(0, &l2cap); psm = sdp_data_alloc(SDP_UINT16, &lp); proto[0] = sdp_list_append(proto[0], psm); apseq = sdp_list_append(0, proto[0]); sdp_uuid16_create(&avdtp, AVDTP_UUID); proto[1] = sdp_list_append(0, &avdtp); version = sdp_data_alloc(SDP_UINT16, &ver); proto[1] = sdp_list_append(proto[1], version); apseq = sdp_list_append(apseq, proto[1]); aproto = sdp_list_append(0, apseq); sdp_set_access_protos(&record, aproto); features = sdp_data_alloc(SDP_UINT16, &feat); sdp_attr_add(&record, SDP_ATTR_SUPPORTED_FEATURES, features); sdp_set_info_attr(&record, "Audio Source", 0, 0); if (sdp_gen_record_pdu(&record, buf) < 0) ret = -1; else ret = 0; free(psm); free(version); sdp_list_free(proto[0], 0); sdp_list_free(proto[1], 0); sdp_list_free(apseq, 0); sdp_list_free(pfseq, 0); sdp_list_free(aproto, 0); sdp_list_free(root, 0); sdp_list_free(svclass_id, 0); sdp_list_free(record.attrlist, (sdp_free_func_t) sdp_data_free);
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -