DtkBluetooth
BlueZ DBus interface binding for Qt
dbluetoothrequest.h
1// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
2//
3// SPDX-License-Identifier: LGPL-3.0-or-later
4
5#ifndef DBLUETOOTHREQUEST_H
6#define DBLUETOOTHREQUEST_H
7
8#include "dbluetoothtypes.h"
9#include <QDBusMessage>
10#include <QDBusConnection>
11#include <QDebug>
12#include <QStringBuilder>
13
14DBLUETOOTH_BEGIN_NAMESPACE
15
16template <typename T = void>
18{
19public:
20 DRequest() = default;
21 ~DRequest() = default;
22
23 explicit DRequest(RequestDest dest, const QDBusMessage &msg)
24 : m_dest(dest)
25 , m_msg(msg){};
26
27 explicit DRequest(RequestDest dest, QDBusMessage &&msg)
28 : m_dest(dest)
29 , m_msg(std::move(msg))
30 {
31 }
32
33 DRequest(const DRequest &other)
34 : m_dest(other.m_dest)
35 , m_msg(other.m_msg)
36 {
37 }
38
39 DRequest(DRequest &&other)
40 : m_dest(other.m_dest)
41 , m_msg(std::move(other.m_msg))
42 {
43 }
44
45 DRequest &operator=(const DRequest &other)
46 {
47 m_dest = other.m_dest;
48 m_msg = other.m_msg;
49 return *this;
50 }
51
52 DRequest &operator=(DRequest &&other) noexcept
53 {
54 m_dest = other.m_dest;
55 m_msg = std::move(other.m_msg);
56 return *this;
57 }
58
59 bool accept(const T &value) const
60 {
61 QDBusMessage reply{m_msg.createReply(QVariant::fromValue<T>(value))};
62 return sendDBusMessage(reply);
63 }
64
65 bool reject() const
66 {
67 const QDBusMessage &reply =
68 m_msg.createErrorReply(interfaceName() % QStringLiteral(".Rejected"), QStringLiteral("Rejected"));
69 return sendDBusMessage(reply);
70 }
71
72 bool cancel() const
73 {
74 const QDBusMessage &reply =
75 m_msg.createErrorReply(interfaceName() % QStringLiteral(".Canceled"), QStringLiteral("Canceled"));
76 return sendDBusMessage(reply);
77 }
78
79private:
80 QString interfaceName() const
81 {
82 switch (m_dest) {
83 case RequestDest::OrgBluezAgent:
84 return QStringLiteral("org.bluez.Agent1");
85 case RequestDest::OrgBluezObexAgent:
86 return QStringLiteral("org.bluez.obex.Agent1");
87 default: {
88 qWarning() << "unexpected bluez interface";
89 return QString{};
90 }
91 }
92 }
93
94 bool sendDBusMessage(const QDBusMessage &msg) const
95 {
96#ifdef USE_FAKE_INTERFACE
97 const auto &Connection = QDBusConnection::sessionBus();
98#else
99 const auto &Connection = QDBusConnection::systemBus();
100#endif
101 switch (m_dest) {
102 case RequestDest::OrgBluezAgent:
103 return Connection.send(msg);
104 case RequestDest::OrgBluezObexAgent:
105 return QDBusConnection::sessionBus().send(msg);
106 default: {
107 qWarning() << "unexpected bluez interface";
108 return false;
109 }
110 }
111 }
112
113 RequestDest m_dest;
114 QDBusMessage m_msg;
115};
116
117template <>
118class DRequest<void>
119{
120public:
121 DRequest() = default;
122 ~DRequest() = default;
123
124 explicit DRequest(RequestDest dest, const QDBusMessage &msg)
125 : m_dest(dest)
126 , m_msg(msg){};
127
128 explicit DRequest(RequestDest dest, QDBusMessage &&msg)
129 : m_dest(dest)
130 , m_msg(std::move(msg))
131 {
132 }
133
134 DRequest(const DRequest &other)
135 : m_dest(other.m_dest)
136 , m_msg(other.m_msg)
137 {
138 }
139
140 DRequest(DRequest &&other)
141 : m_dest(other.m_dest)
142 , m_msg(std::move(other.m_msg))
143 {
144 }
145
146 DRequest &operator=(const DRequest &other)
147 {
148 m_dest = other.m_dest;
149 m_msg = other.m_msg;
150 return *this;
151 }
152
153 DRequest &operator=(DRequest &&other) noexcept
154 {
155 m_dest = other.m_dest;
156 m_msg = std::move(other.m_msg);
157 return *this;
158 }
159
160 bool accept() const
161 {
162 const QDBusMessage &reply{m_msg.createReply()};
163 return sendDBusMessage(reply);
164 }
165
166 bool reject() const
167 {
168 const QDBusMessage &reply =
169 m_msg.createErrorReply(interfaceName() % QStringLiteral(".Rejected"), QStringLiteral("Rejected"));
170 return sendDBusMessage(reply);
171 }
172
173 bool cancel() const
174 {
175 const QDBusMessage &reply =
176 m_msg.createErrorReply(interfaceName() % QStringLiteral(".Canceled"), QStringLiteral("Canceled"));
177 return sendDBusMessage(reply);
178 }
179
180private:
181 QString interfaceName() const
182 {
183 switch (m_dest) {
184 case RequestDest::OrgBluezAgent:
185 return QStringLiteral("org.bluez.Agent1");
186 case RequestDest::OrgBluezObexAgent:
187 return QStringLiteral("org.bluez.obex.Agent1");
188 default: {
189 qWarning() << "unexpected bluez interface";
190 return QString{};
191 }
192 }
193 }
194
195 bool sendDBusMessage(const QDBusMessage &msg) const
196 {
197#ifdef USE_FAKE_INTERFACE
198 const auto &Connection = QDBusConnection::sessionBus();
199#else
200 const auto &Connection = QDBusConnection::systemBus();
201#endif
202 switch (m_dest) {
203 case RequestDest::OrgBluezAgent:
204 return Connection.send(msg);
205 case RequestDest::OrgBluezObexAgent:
206 return QDBusConnection::sessionBus().send(msg);
207 default: {
208 qWarning() << "unexpected bluez interface";
209 return false;
210 }
211 }
212 }
213
214 RequestDest m_dest;
215 QDBusMessage m_msg;
216};
217
218DBLUETOOTH_END_NAMESPACE
219
220#endif
对于D-Bus请求的简单封装, 方便在自定义代理是处理来自蓝牙服务的请求
Definition: dbluetoothrequest.h:18
bool accept(const T &value) const
接受来自服务的请求
Definition: dbluetoothrequest.h:59
bool cancel() const
取消当前请求
Definition: dbluetoothrequest.h:72
bool reject() const
拒绝来自服务的请求
Definition: dbluetoothrequest.h:65
一些自定义类型和枚举
RequestDest
蓝牙请求的目标服务
Definition: dbluetoothtypes.h:18