static struct a2dp_sep *a2dp_add_sep(struct a2dp_server *server, uint8_t type, uint8_t codec, gboolean delay_reporting) { struct a2dp_sep *sep; GSList **l; uint32_t *record_id; sdp_record_t *record; struct avdtp_sep_ind *ind; sep = g_new0(struct a2dp_sep, 1); ind = (codec == A2DP_CODEC_MPEG12) ? &mpeg_ind : &sbc_ind; sep->sep = avdtp_register_sep(&server->src, type, AVDTP_MEDIA_TYPE_AUDIO, codec, delay_reporting, ind, &cfm, sep); if (sep->sep == NULL) { g_free(sep); return NULL; } sep->codec = codec; sep->type = type; sep->delay_reporting = delay_reporting; if (type == AVDTP_SEP_TYPE_SOURCE) { l = &server->sources; record_id = &server->source_record_id; } else { l = &server->sinks; record_id = &server->sink_record_id; } if (*record_id != 0) goto add; record = a2dp_record(type, server->version); if (!record) { error("Unable to allocate new service record"); avdtp_unregister_sep(sep->sep); g_free(sep); return NULL; } if (add_record_to_server(&server->src, record) < 0) { error("Unable to register A2DP service record"); \ sdp_record_free(record); avdtp_unregister_sep(sep->sep); g_free(sep); return NULL; } *record_id = record->handle; add: *l = g_slist_append(*l, sep); return sep; }
bool bt_a2dp_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode) { GError *err = NULL; sdp_record_t *rec; DBG(""); bacpy(&adapter_addr, addr); server = bt_io_listen(connect_cb, NULL, NULL, NULL, &err, BT_IO_OPT_SOURCE_BDADDR, &adapter_addr, BT_IO_OPT_PSM, AVDTP_PSM, BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM, BT_IO_OPT_MASTER, true, BT_IO_OPT_INVALID); if (!server) { error("Failed to listen on AVDTP channel: %s", err->message); g_error_free(err); return false; } rec = a2dp_record(); if (!rec) { error("Failed to allocate A2DP record"); goto fail; } if (bt_adapter_add_record(rec, SVC_HINT_CAPTURING) < 0) { error("Failed to register A2DP record"); sdp_record_free(rec); goto fail; } record_id = rec->handle; hal_ipc = ipc; ipc_register(hal_ipc, HAL_SERVICE_ID_A2DP, cmd_handlers, G_N_ELEMENTS(cmd_handlers)); if (bt_audio_register(audio_disconnected)) return true; fail: g_io_channel_shutdown(server, TRUE, NULL); g_io_channel_unref(server); server = NULL; return false; }