File indexing completed on 2024-05-12 04:58:51
0001 /** 0002 * SPDX-FileCopyrightText: 2019 Matthijs Tijink <matthijstijink@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 #ifndef CONNECTIONMULTIPLEXER_H 0008 #define CONNECTIONMULTIPLEXER_H 0009 0010 #include <QByteArray> 0011 #include <QHash> 0012 #include <QObject> 0013 #include <QSharedPointer> 0014 #include <memory> 0015 0016 class QBluetoothUuid; 0017 class MultiplexChannel; 0018 class MultiplexChannelState; 0019 class QBluetoothSocket; 0020 0021 /** 0022 * An utility class to split a single (bluetooth) connection to multiple independent channels. 0023 * By default (and without needing any communication with the other endpoint), a single default channel is open. 0024 * 0025 * Destroying/closing this object will automatically close all channels. 0026 */ 0027 class ConnectionMultiplexer : public QObject 0028 { 0029 Q_OBJECT 0030 public: 0031 ConnectionMultiplexer(QBluetoothSocket *socket, QObject *parent = nullptr); 0032 ~ConnectionMultiplexer(); 0033 0034 /** 0035 * Open a new channel within this connection. 0036 * 0037 * @return The uuid to refer to this channel. 0038 * @see getChannel() 0039 */ 0040 QBluetoothUuid newChannel(); 0041 /** 0042 * Get the channel device for the specified channel uuid. 0043 * If the channel does not exist, this will return a null pointer. 0044 * 0045 * A channel is guaranteed to exist until the first call to get it. 0046 * @param channelId The channel uuid 0047 * @return A shared pointer to the channel object 0048 * @see getDefaultChannel() 0049 */ 0050 std::unique_ptr<MultiplexChannel> getChannel(QBluetoothUuid channelId); 0051 /** 0052 * Get the default channel. 0053 * 0054 * @see getChannel() 0055 */ 0056 std::unique_ptr<MultiplexChannel> getDefaultChannel(); 0057 0058 /** 0059 * Close all channels and the underlying connection. 0060 */ 0061 void close(); 0062 0063 /** 0064 * Check if the underlying connection is still open. 0065 * @return True if the connection is open 0066 * @see close() 0067 */ 0068 bool isOpen() const; 0069 0070 private: 0071 /** 0072 * The underlying connection 0073 */ 0074 QBluetoothSocket *mSocket; 0075 /** 0076 * The buffer of to-be-written bytes 0077 */ 0078 QByteArray to_write_bytes; 0079 /** 0080 * The channels not requested by the user yet 0081 */ 0082 QHash<QBluetoothUuid, MultiplexChannel *> unrequested_channels; 0083 /** 0084 * All channels currently open 0085 */ 0086 QHash<QBluetoothUuid, QSharedPointer<MultiplexChannelState>> channels; 0087 /** 0088 * True once the other side has sent its protocol version 0089 */ 0090 bool receivedProtocolVersion; 0091 0092 /** 0093 * Slot for connection reading 0094 */ 0095 void readyRead(); 0096 /** 0097 * Slot for disconnection 0098 */ 0099 void disconnected(); 0100 /** 0101 * Slot for progress in writing data/new data available to be written 0102 */ 0103 void bytesWritten(); 0104 /** 0105 * Tries to parse a single connection message. 0106 * 0107 * @return True if a message was parsed successfully. 0108 */ 0109 bool tryParseMessage(); 0110 /** 0111 * Add a new channel. Assumes that the communication about this channel is done 0112 * (i.e. the other endpoint also knows this channel exists). 0113 * 0114 * @param new_id The channel uuid 0115 */ 0116 void addChannel(QBluetoothUuid new_id); 0117 0118 /** 0119 * Slot for closing a channel 0120 */ 0121 void closeChannel(QBluetoothUuid channelId); 0122 /** 0123 * Slot for writing a channel's data to the other endpoint 0124 */ 0125 void channelCanWrite(QBluetoothUuid channelId); 0126 /** 0127 * Slot for indicating that a channel can receive more data 0128 */ 0129 void channelCanRead(QBluetoothUuid channelId); 0130 /** 0131 * Slot for removing a channel from tracking 0132 */ 0133 void removeChannel(QBluetoothUuid channelId); 0134 }; 0135 0136 #endif