1// Copyright (C) 2011-2012 Denis Shienkov <denis.shienkov@gmail.com>
2// Copyright (C) 2011 Sergey Belyashov <Sergey.Belyashov@gmail.com>
3// Copyright (C) 2012 Laszlo Papp <lpapp@kde.org>
4// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
5
6#ifndef QSERIALPORT_P_H
7#define QSERIALPORT_P_H
8
9//
10// W A R N I N G
11// -------------
12//
13// This file is not part of the Qt API. It exists purely as an
14// implementation detail. This header file may change from version to
15// version without notice, or even be removed.
16//
17// We mean it.
18//
19
20#include "qserialport.h"
21
22#include <qdeadlinetimer.h>
23
24#include <private/qiodevice_p.h>
25#include <private/qproperty_p.h>
26
27#include <memory>
28
29#if defined(Q_OS_WIN32)
30# include <qt_windows.h>
31#elif defined(Q_OS_UNIX)
32# include <QtCore/qlockfile.h>
33# include <QtCore/qfileinfo.h>
34# include <QtCore/qstringlist.h>
35# include <limits.h>
36# include <termios.h>
37# ifdef Q_OS_ANDROID
38struct serial_struct {
39 int type;
40 int line;
41 unsigned int port;
42 int irq;
43 int flags;
44 int xmit_fifo_size;
45 int custom_divisor;
46 int baud_base;
47 unsigned short close_delay;
48 char io_type;
49 char reserved_char[1];
50 int hub6;
51 unsigned short closing_wait;
52 unsigned short closing_wait2;
53 unsigned char *iomem_base;
54 unsigned short iomem_reg_shift;
55 unsigned int port_high;
56 unsigned long iomap_base;
57};
58# define ASYNC_SPD_CUST 0x0030
59# define ASYNC_SPD_MASK 0x1030
60# define PORT_UNKNOWN 0
61# elif defined(Q_OS_LINUX)
62# include <linux/serial.h>
63# endif
64#else
65# error Unsupported OS
66#endif
67
68#ifndef QSERIALPORT_BUFFERSIZE
69#define QSERIALPORT_BUFFERSIZE 32768
70#endif
71
72QT_BEGIN_NAMESPACE
73
74class QWinOverlappedIoNotifier;
75class QTimer;
76class QSocketNotifier;
77
78#if defined(Q_OS_UNIX)
79QString serialPortLockFilePath(const QString &portName);
80#endif
81
82class QSerialPortErrorInfo
83{
84public:
85 QSerialPortErrorInfo(QSerialPort::SerialPortError newErrorCode = QSerialPort::UnknownError,
86 const QString &newErrorString = QString());
87 QSerialPort::SerialPortError errorCode = QSerialPort::UnknownError;
88 QString errorString;
89};
90
91class QSerialPortPrivate : public QIODevicePrivate
92{
93public:
94 Q_DECLARE_PUBLIC(QSerialPort)
95
96 QSerialPortPrivate();
97
98 bool open(QIODevice::OpenMode mode);
99 void close();
100
101 QSerialPort::PinoutSignals pinoutSignals();
102
103 bool setDataTerminalReady(bool set);
104 bool setRequestToSend(bool set);
105
106 bool flush();
107 bool clear(QSerialPort::Directions directions);
108
109 bool sendBreak(int duration);
110 bool setBreakEnabled(bool set);
111
112 bool waitForReadyRead(int msec);
113 bool waitForBytesWritten(int msec);
114
115 bool setBaudRate();
116 bool setBaudRate(qint32 baudRate, QSerialPort::Directions directions);
117 bool setDataBits(QSerialPort::DataBits dataBits);
118 bool setParity(QSerialPort::Parity parity);
119 bool setStopBits(QSerialPort::StopBits stopBits);
120 bool setFlowControl(QSerialPort::FlowControl flowControl);
121
122 QSerialPortErrorInfo getSystemError(int systemErrorCode = -1) const;
123
124 void setError(const QSerialPortErrorInfo &errorInfo);
125
126 qint64 writeData(const char *data, qint64 maxSize);
127
128 bool initialize(QIODevice::OpenMode mode);
129
130 static QString portNameToSystemLocation(const QString &port);
131 static QString portNameFromSystemLocation(const QString &location);
132
133 static QList<qint32> standardBaudRates();
134
135 qint64 readBufferMaxSize = 0;
136
137 void setBindableError(QSerialPort::SerialPortError error)
138 { setError(error); }
139 Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS(QSerialPortPrivate, QSerialPort::SerialPortError, error,
140 &QSerialPortPrivate::setBindableError, QSerialPort::NoError)
141
142 QString systemLocation;
143 qint32 inputBaudRate = QSerialPort::Baud9600;
144 qint32 outputBaudRate = QSerialPort::Baud9600;
145
146 bool setBindableDataBits(QSerialPort::DataBits dataBits)
147 { return q_func()->setDataBits(dataBits); }
148 Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS(QSerialPortPrivate, QSerialPort::DataBits, dataBits,
149 &QSerialPortPrivate::setBindableDataBits, QSerialPort::Data8)
150
151 bool setBindableParity(QSerialPort::Parity parity)
152 { return q_func()->setParity(parity); }
153 Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS(QSerialPortPrivate, QSerialPort::Parity, parity,
154 &QSerialPortPrivate::setBindableParity, QSerialPort::NoParity)
155
156 bool setBindableStopBits(QSerialPort::StopBits stopBits)
157 { return q_func()->setStopBits(stopBits); }
158 Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS(QSerialPortPrivate, QSerialPort::StopBits, stopBits,
159 &QSerialPortPrivate::setBindableStopBits, QSerialPort::OneStop)
160
161 bool setBindableFlowControl(QSerialPort::FlowControl flowControl)
162 { return q_func()->setFlowControl(flowControl); }
163 Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS(QSerialPortPrivate, QSerialPort::FlowControl, flowControl,
164 &QSerialPortPrivate::setBindableFlowControl, QSerialPort::NoFlowControl)
165
166 bool settingsRestoredOnClose = true;
167
168 bool setBindableBreakEnabled(bool isBreakEnabled)
169 { return q_func()->setBreakEnabled(isBreakEnabled); }
170 Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS(QSerialPortPrivate, bool, isBreakEnabled,
171 &QSerialPortPrivate::setBindableBreakEnabled, false)
172
173 bool startAsyncRead();
174
175#if defined(Q_OS_WIN32)
176
177 bool setDcb(DCB *dcb);
178 bool getDcb(DCB *dcb);
179 OVERLAPPED *waitForNotified(QDeadlineTimer deadline);
180
181 qint64 queuedBytesCount(QSerialPort::Direction direction) const;
182
183 bool completeAsyncCommunication(qint64 bytesTransferred);
184 bool completeAsyncRead(qint64 bytesTransferred);
185 bool completeAsyncWrite(qint64 bytesTransferred);
186
187 bool startAsyncCommunication();
188 bool _q_startAsyncWrite();
189 void _q_notified(DWORD numberOfBytes, DWORD errorCode, OVERLAPPED *overlapped);
190
191 void emitReadyRead();
192
193 DCB restoredDcb;
194 COMMTIMEOUTS currentCommTimeouts;
195 COMMTIMEOUTS restoredCommTimeouts;
196 HANDLE handle = INVALID_HANDLE_VALUE;
197 QByteArray readChunkBuffer;
198 QByteArray writeChunkBuffer;
199 bool communicationStarted = false;
200 bool writeStarted = false;
201 bool readStarted = false;
202 QWinOverlappedIoNotifier *notifier = nullptr;
203 QTimer *startAsyncWriteTimer = nullptr;
204 OVERLAPPED communicationOverlapped;
205 OVERLAPPED readCompletionOverlapped;
206 OVERLAPPED writeCompletionOverlapped;
207 DWORD triggeredEventMask = 0;
208
209#elif defined(Q_OS_UNIX)
210
211 static qint32 settingFromBaudRate(qint32 baudRate);
212
213 bool setTermios(const termios *tio);
214 bool getTermios(termios *tio);
215
216 bool setCustomBaudRate(qint32 baudRate, QSerialPort::Directions directions);
217 bool setStandardBaudRate(qint32 baudRate, QSerialPort::Directions directions);
218
219 bool isReadNotificationEnabled() const;
220 void setReadNotificationEnabled(bool enable);
221 bool isWriteNotificationEnabled() const;
222 void setWriteNotificationEnabled(bool enable);
223
224 bool waitForReadOrWrite(bool *selectForRead, bool *selectForWrite,
225 bool checkRead, bool checkWrite,
226 int msecs);
227
228 qint64 readFromPort(char *data, qint64 maxSize);
229 qint64 writeToPort(const char *data, qint64 maxSize);
230
231#ifndef CMSPAR
232 qint64 writePerChar(const char *data, qint64 maxSize);
233#endif
234
235 bool readNotification();
236 bool startAsyncWrite();
237 bool completeAsyncWrite();
238
239 struct termios restoredTermios;
240 int descriptor = -1;
241
242 QSocketNotifier *readNotifier = nullptr;
243 QSocketNotifier *writeNotifier = nullptr;
244
245 bool readPortNotifierCalled = false;
246 bool readPortNotifierState = false;
247 bool readPortNotifierStateSet = false;
248
249 bool emittedReadyRead = false;
250 bool emittedBytesWritten = false;
251
252 qint64 pendingBytesWritten = 0;
253 bool writeSequenceStarted = false;
254
255 std::unique_ptr<QLockFile> lockFileScopedPointer;
256
257#endif
258};
259
260QT_END_NAMESPACE
261
262#endif // QSERIALPORT_P_H
263

source code of qtserialport/src/serialport/qserialport_p.h