BluezQt

mediaendpoint.cpp
1/*
2 * BluezQt - Asynchronous Bluez wrapper library
3 *
4 * SPDX-FileCopyrightText: 2018 Manuel Weichselbaumer <mincequi@web.de>
5 *
6 * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
7 */
8
9#include "mediaendpoint.h"
10#include "a2dp-codecs.h"
11#include "mediaendpoint_p.h"
12
13namespace BluezQt
14{
16 : QObject(parent)
17 , d(new MediaEndpointPrivate(configuration))
18{
19}
20
22
24{
25 return d->m_objectPath;
26}
27
28const QVariantMap &MediaEndpoint::properties() const
29{
30 return d->m_properties;
31}
32
33void MediaEndpoint::setConfiguration(const QString &transportObjectPath, const QVariantMap &properties)
34{
35 Q_EMIT configurationSet(transportObjectPath, properties);
36}
37
38void MediaEndpoint::selectConfiguration(const QByteArray &capabilities, const Request<QByteArray> &request)
39{
40 switch (d->m_configuration.codec) {
41 case MediaEndpoint::Codec::Sbc: {
42 if (capabilities.size() != sizeof(a2dp_sbc_t)) {
44 request.reject();
45 return;
46 }
47
48 a2dp_sbc_t caps = *reinterpret_cast<const a2dp_sbc_t *>(capabilities.constData());
49 if (caps.frequency & SBC_SAMPLING_FREQ_44100) {
50 caps.frequency = SBC_SAMPLING_FREQ_44100;
51 } else if (caps.frequency & SBC_SAMPLING_FREQ_48000) {
52 caps.frequency = SBC_SAMPLING_FREQ_48000;
53 } else {
54 break;
55 }
56
57 if (caps.channel_mode & SBC_CHANNEL_MODE_STEREO) {
58 caps.channel_mode = SBC_CHANNEL_MODE_STEREO;
59 } else if (caps.channel_mode & SBC_CHANNEL_MODE_JOINT_STEREO) {
60 caps.channel_mode = SBC_CHANNEL_MODE_JOINT_STEREO;
61 } else {
62 break;
63 }
64
65 if (caps.block_length & SBC_BLOCK_LENGTH_16) {
66 caps.block_length = SBC_BLOCK_LENGTH_16;
67 } else if (caps.block_length & SBC_BLOCK_LENGTH_12) {
68 caps.block_length = SBC_BLOCK_LENGTH_12;
69 } else if (caps.block_length & SBC_BLOCK_LENGTH_8) {
70 caps.block_length = SBC_BLOCK_LENGTH_8;
71 } else if (caps.block_length & SBC_BLOCK_LENGTH_4) {
72 caps.block_length = SBC_BLOCK_LENGTH_4;
73 } else {
74 break;
75 }
76
77 if (caps.subbands & SBC_SUBBANDS_8) {
78 caps.subbands = SBC_SUBBANDS_8;
79 } else if (caps.subbands & SBC_SUBBANDS_4) {
80 caps.subbands = SBC_SUBBANDS_4;
81 } else {
82 break;
83 }
84
85 if (caps.allocation_method & SBC_ALLOCATION_LOUDNESS) {
86 caps.allocation_method = SBC_ALLOCATION_LOUDNESS;
87 } else if (caps.allocation_method & SBC_ALLOCATION_SNR) {
88 caps.allocation_method = SBC_ALLOCATION_SNR;
89 } else {
90 break;
91 }
92
93 caps.min_bitpool = std::max(caps.min_bitpool, static_cast<uint8_t>(MIN_BITPOOL));
94 caps.max_bitpool = std::min(caps.max_bitpool, static_cast<uint8_t>(MAX_BITPOOL));
95
96 const QByteArray configuration(reinterpret_cast<const char *>(&caps), sizeof(caps));
97 Q_EMIT configurationSelected(capabilities, configuration);
98 request.accept(configuration);
99 return;
100
101 break;
102 }
103 case MediaEndpoint::Codec::Aac:
104 if (capabilities.size() != sizeof(a2dp_aac_t)) {
105 Q_EMIT configurationSelected(capabilities, QByteArray());
106 request.reject();
107 return;
108 }
109
110 // TODO: implement AAC. However selectConfiguration seems not to be used by iOS nor Android.
111 Q_EMIT configurationSelected(capabilities, QByteArray());
112 request.reject();
113 return;
114
115 break;
116 }
117
118 Q_EMIT configurationSelected(capabilities, QByteArray());
119 request.reject();
120}
121
122void MediaEndpoint::clearConfiguration(const QString &transportObjectPath)
123{
124 Q_EMIT configurationCleared(transportObjectPath);
125}
126
128{
129}
130
131} // namespace BluezQt
132
133#include "moc_mediaendpoint.cpp"
void configurationSet(const QString &transportObjectPath, const QVariantMap &properties)
Indicates that configuration was set for transport.
virtual QDBusObjectPath objectPath() const
D-Bus object path of the MediaEndpoint.
virtual void clearConfiguration(const QString &transportObjectPath)
Clear transport configuration.
virtual void setConfiguration(const QString &transportObjectPath, const QVariantMap &properties)
Set configuration for the transport.
virtual void release()
Indicates that the MediaEndpoint was unregistered.
~MediaEndpoint() override
Destroys a MediaEndpoint object.
MediaEndpoint(const Configuration &configuration, QObject *parent=nullptr)
Creates a new MediaEndpoint object.
void configurationCleared(const QString &transportObjectPath)
Indicates that configuration was cleared for transport.
virtual void selectConfiguration(const QByteArray &capabilities, const Request< QByteArray > &request)
Select preferable configuration from the supported capabilities.
virtual const QVariantMap & properties() const
Properties of the endpoint.
void configurationSelected(const QByteArray &capabilities, const QByteArray &configuration)
Indicates that configuration was selected.
D-Bus request.
void accept(T returnValue) const
Accepts the request.
Definition request.cpp:126
void reject() const
Rejects the request.
Definition request.cpp:132
Q_EMITQ_EMIT
Configuration for MediaEndpoint construction.
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Nov 29 2024 11:46:08 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.