1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef HCIMANAGER_P_H
5#define HCIMANAGER_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtCore/QObject>
19#include <QtCore/QList>
20#include <QtCore/QSet>
21#include <QtCore/QSocketNotifier>
22#include <QtBluetooth/QBluetoothAddress>
23#include "bluez/bluez_data_p.h"
24
25QT_BEGIN_NAMESPACE
26
27class QLowEnergyConnectionParameters;
28
29class HciManager : public QObject
30{
31 Q_OBJECT
32public:
33 enum class HciEvent {
34 EVT_INQUIRY_COMPLETE = 0x01,
35 EVT_INQUIRY_RESULT = 0x02,
36 EVT_CONN_COMPLETE = 0x03,
37 EVT_CONN_REQUEST = 0x04,
38 EVT_DISCONN_COMPLETE = 0x05,
39 EVT_AUTH_COMPLETE = 0x06,
40 EVT_REMOTE_NAME_REQ_COMPLETE = 0x07,
41 EVT_ENCRYPT_CHANGE = 0x08,
42 EVT_CHANGE_CONN_LINK_KEY_COMPLETE = 0x09,
43 EVT_MASTER_LINK_KEY_COMPLETE = 0x0A,
44 EVT_READ_REMOTE_FEATURES_COMPLETE = 0x0B,
45 EVT_READ_REMOTE_VERSION_COMPLETE = 0x0C,
46 EVT_QOS_SETUP_COMPLETE = 0x0D,
47 EVT_CMD_COMPLETE = 0x0E,
48 EVT_CMD_STATUS = 0x0F,
49 EVT_HARDWARE_ERROR = 0x10,
50 EVT_FLUSH_OCCURRED = 0x11,
51 EVT_ROLE_CHANGE = 0x12,
52 EVT_NUM_COMP_PKTS = 0x13,
53 EVT_MODE_CHANGE = 0x14,
54 EVT_RETURN_LINK_KEYS = 0x15,
55 EVT_PIN_CODE_REQ = 0x16,
56 EVT_LINK_KEY_REQ = 0x17,
57 EVT_LINK_KEY_NOTIFY = 0x18,
58 EVT_LOOPBACK_COMMAND = 0x19,
59 EVT_DATA_BUFFER_OVERFLOW = 0x1A,
60 EVT_MAX_SLOTS_CHANGE = 0x1B,
61 EVT_READ_CLOCK_OFFSET_COMPLETE = 0x1C,
62 EVT_CONN_PTYPE_CHANGED = 0x1D,
63 EVT_QOS_VIOLATION = 0x1E,
64 EVT_PSCAN_REP_MODE_CHANGE = 0x20,
65 EVT_FLOW_SPEC_COMPLETE = 0x21,
66 EVT_INQUIRY_RESULT_WITH_RSSI = 0x22,
67 EVT_READ_REMOTE_EXT_FEATURES_COMPLETE = 0x23,
68 EVT_SYNC_CONN_COMPLETE = 0x2C,
69 EVT_SYNC_CONN_CHANGED = 0x2D,
70 EVT_SNIFF_SUBRATING = 0x2E,
71 EVT_EXTENDED_INQUIRY_RESULT = 0x2F,
72 EVT_ENCRYPTION_KEY_REFRESH_COMPLETE = 0x30,
73 EVT_IO_CAPABILITY_REQUEST = 0x31,
74 EVT_IO_CAPABILITY_RESPONSE = 0x32,
75 EVT_USER_CONFIRM_REQUEST = 0x33,
76 EVT_USER_PASSKEY_REQUEST = 0x34,
77 EVT_REMOTE_OOB_DATA_REQUEST = 0x35,
78 EVT_SIMPLE_PAIRING_COMPLETE = 0x36,
79 EVT_LINK_SUPERVISION_TIMEOUT_CHANGED = 0x38,
80 EVT_ENHANCED_FLUSH_COMPLETE = 0x39,
81 EVT_USER_PASSKEY_NOTIFY = 0x3B,
82 EVT_KEYPRESS_NOTIFY = 0x3C,
83 EVT_REMOTE_HOST_FEATURES_NOTIFY = 0x3D,
84 EVT_LE_META_EVENT = 0x3E,
85 EVT_PHYSICAL_LINK_COMPLETE = 0x40,
86 EVT_CHANNEL_SELECTED = 0x41,
87 EVT_DISCONNECT_PHYSICAL_LINK_COMPLETE = 0x42,
88 EVT_PHYSICAL_LINK_LOSS_EARLY_WARNING = 0x43,
89 EVT_PHYSICAL_LINK_RECOVERY = 0x44,
90 EVT_LOGICAL_LINK_COMPLETE = 0x45,
91 EVT_DISCONNECT_LOGICAL_LINK_COMPLETE = 0x46,
92 EVT_FLOW_SPEC_MODIFY_COMPLETE = 0x47,
93 EVT_NUMBER_COMPLETED_BLOCKS = 0x48,
94 EVT_AMP_STATUS_CHANGE = 0x4D,
95 EVT_TESTING = 0xFE,
96 EVT_VENDOR = 0xFF,
97 EVT_STACK_INTERNAL = 0xFD
98 };
99 Q_ENUM(HciEvent);
100
101 enum class HciError {
102 HCI_SUCCESS = 0x00, // added for convenience, not in bluez code
103 HCI_UNKNOWN_COMMAND = 0x01,
104 HCI_NO_CONNECTION = 0x02,
105 HCI_HARDWARE_FAILURE = 0x03,
106 HCI_PAGE_TIMEOUT = 0x04,
107 HCI_AUTHENTICATION_FAILURE = 0x05,
108 HCI_PIN_OR_KEY_MISSING = 0x06,
109 HCI_MEMORY_FULL = 0x07,
110 HCI_CONNECTION_TIMEOUT = 0x08,
111 HCI_MAX_NUMBER_OF_CONNECTIONS = 0x09,
112 HCI_MAX_NUMBER_OF_SCO_CONNECTIONS = 0x0a,
113 HCI_ACL_CONNECTION_EXISTS = 0x0b,
114 HCI_COMMAND_DISALLOWED = 0x0c,
115 HCI_REJECTED_LIMITED_RESOURCES = 0x0d,
116 HCI_REJECTED_SECURITY = 0x0e,
117 HCI_REJECTED_PERSONAL = 0x0f,
118 HCI_HOST_TIMEOUT = 0x10,
119 HCI_UNSUPPORTED_FEATURE = 0x11,
120 HCI_INVALID_PARAMETERS = 0x12,
121 HCI_OE_USER_ENDED_CONNECTION = 0x13,
122 HCI_OE_LOW_RESOURCES = 0x14,
123 HCI_OE_POWER_OFF = 0x15,
124 HCI_CONNECTION_TERMINATED = 0x16,
125 HCI_REPEATED_ATTEMPTS = 0x17,
126 HCI_PAIRING_NOT_ALLOWED = 0x18,
127 HCI_UNKNOWN_LMP_PDU = 0x19,
128 HCI_UNSUPPORTED_REMOTE_FEATURE = 0x1a,
129 HCI_SCO_OFFSET_REJECTED = 0x1b,
130 HCI_SCO_INTERVAL_REJECTED = 0x1c,
131 HCI_AIR_MODE_REJECTED = 0x1d,
132 HCI_INVALID_LMP_PARAMETERS = 0x1e,
133 HCI_UNSPECIFIED_ERROR = 0x1f,
134 HCI_UNSUPPORTED_LMP_PARAMETER_VALUE = 0x20,
135 HCI_ROLE_CHANGE_NOT_ALLOWED = 0x21,
136 HCI_LMP_RESPONSE_TIMEOUT = 0x22,
137 HCI_LMP_ERROR_TRANSACTION_COLLISION = 0x23,
138 HCI_LMP_PDU_NOT_ALLOWED = 0x24,
139 HCI_ENCRYPTION_MODE_NOT_ACCEPTED = 0x25,
140 HCI_UNIT_LINK_KEY_USED = 0x26,
141 HCI_QOS_NOT_SUPPORTED = 0x27,
142 HCI_INSTANT_PASSED = 0x28,
143 HCI_PAIRING_NOT_SUPPORTED = 0x29,
144 HCI_TRANSACTION_COLLISION = 0x2a,
145 HCI_QOS_UNACCEPTABLE_PARAMETER = 0x2c,
146 HCI_QOS_REJECTED = 0x2d,
147 HCI_CLASSIFICATION_NOT_SUPPORTED = 0x2e,
148 HCI_INSUFFICIENT_SECURITY = 0x2f,
149 HCI_PARAMETER_OUT_OF_RANGE = 0x30,
150 HCI_ROLE_SWITCH_PENDING = 0x32,
151 HCI_SLOT_VIOLATION = 0x34,
152 HCI_ROLE_SWITCH_FAILED = 0x35,
153 HCI_EIR_TOO_LARGE = 0x36,
154 HCI_SIMPLE_PAIRING_NOT_SUPPORTED = 0x37,
155 HCI_HOST_BUSY_PAIRING = 0x38
156 };
157 Q_ENUM(HciError);
158
159 explicit HciManager(const QBluetoothAddress &deviceAdapter);
160 ~HciManager();
161
162 bool isValid() const;
163 bool monitorEvent(HciManager::HciEvent event);
164 bool monitorAclPackets();
165 bool sendCommand(QBluezConst::OpCodeGroupField ogf, QBluezConst::OpCodeCommandField ocf, const QByteArray &parameters);
166
167 void stopEvents();
168 QBluetoothAddress addressForConnectionHandle(quint16 handle) const;
169
170 // active connections
171 QList<quint16> activeLowEnergyConnections() const;
172
173 bool sendConnectionUpdateCommand(quint16 handle, const QLowEnergyConnectionParameters &params);
174 bool sendConnectionParameterUpdateRequest(quint16 handle,
175 const QLowEnergyConnectionParameters &params);
176
177signals:
178 void encryptionChangedEvent(const QBluetoothAddress &address, bool wasSuccess);
179 void commandCompleted(quint16 opCode, quint8 status, const QByteArray &data);
180 void connectionComplete(quint16 handle);
181 void connectionUpdate(quint16 handle, const QLowEnergyConnectionParameters &parameters);
182 void signatureResolvingKeyReceived(quint16 connHandle, bool remoteKey, BluezUint128 csrk);
183
184private slots:
185 void _q_readNotify();
186
187private:
188 int hciForAddress(const QBluetoothAddress &deviceAdapter);
189 void handleHciEventPacket(const quint8 *data, int size);
190 void handleHciAclPacket(const quint8 *data, int size);
191 void handleLeMetaEvent(const quint8 *data);
192
193 int hciSocket;
194 int hciDev;
195 quint8 sigPacketIdentifier = 0;
196 QSocketNotifier *notifier = nullptr;
197 QSet<HciManager::HciEvent> runningEvents;
198};
199
200QT_END_NAMESPACE
201
202#endif // HCIMANAGER_P_H
203

source code of qtconnectivity/src/bluetooth/bluez/hcimanager_p.h