1 | /*!
|
---|
2 | * \file qextserialenumerator.h
|
---|
3 | * \author Michal Policht
|
---|
4 | * \see QextSerialEnumerator
|
---|
5 | */
|
---|
6 |
|
---|
7 | #ifndef _QEXTSERIALENUMERATOR_H_
|
---|
8 | #define _QEXTSERIALENUMERATOR_H_
|
---|
9 |
|
---|
10 |
|
---|
11 | #include <QString>
|
---|
12 | #include <QList>
|
---|
13 | #include <QObject>
|
---|
14 | #include "qextserialport_global.h"
|
---|
15 |
|
---|
16 | #ifdef Q_OS_WIN
|
---|
17 | #include <windows.h>
|
---|
18 | #include <setupapi.h>
|
---|
19 | #include <dbt.h>
|
---|
20 | #endif /*Q_OS_WIN*/
|
---|
21 |
|
---|
22 | #ifdef Q_OS_MAC
|
---|
23 | #include <IOKit/usb/IOUSBLib.h>
|
---|
24 | #endif
|
---|
25 |
|
---|
26 | /*!
|
---|
27 | * Structure containing port information.
|
---|
28 | */
|
---|
29 | struct QextPortInfo {
|
---|
30 | QString portName; ///< Port name.
|
---|
31 | QString physName; ///< Physical name.
|
---|
32 | QString friendName; ///< Friendly name.
|
---|
33 | QString enumName; ///< Enumerator name.
|
---|
34 | int vendorID; ///< Vendor ID.
|
---|
35 | int productID; ///< Product ID
|
---|
36 | };
|
---|
37 |
|
---|
38 | #ifdef Q_OS_WIN
|
---|
39 | #ifdef QT_GUI_LIB
|
---|
40 | #include <QWidget>
|
---|
41 | class QextSerialEnumerator;
|
---|
42 |
|
---|
43 | class QextSerialRegistrationWidget : public QWidget
|
---|
44 | {
|
---|
45 | Q_OBJECT
|
---|
46 | public:
|
---|
47 | QextSerialRegistrationWidget( QextSerialEnumerator* qese ) {
|
---|
48 | this->qese = qese;
|
---|
49 | }
|
---|
50 | ~QextSerialRegistrationWidget( ) { }
|
---|
51 |
|
---|
52 | protected:
|
---|
53 | QextSerialEnumerator* qese;
|
---|
54 | bool winEvent( MSG* message, long* result );
|
---|
55 | };
|
---|
56 | #endif // QT_GUI_LIB
|
---|
57 | #endif // Q_OS_WIN
|
---|
58 |
|
---|
59 | /*!
|
---|
60 | Provides list of ports available in the system.
|
---|
61 |
|
---|
62 | \section Usage
|
---|
63 | To poll the system for a list of connected devices, simply use getPorts(). Each
|
---|
64 | QextPortInfo structure will populated with information about the corresponding device.
|
---|
65 |
|
---|
66 | \b Example
|
---|
67 | \code
|
---|
68 | QList<QextPortInfo> ports = QextSerialEnumerator::getPorts();
|
---|
69 | foreach( QextPortInfo port, ports ) {
|
---|
70 | // inspect port...
|
---|
71 | }
|
---|
72 | \endcode
|
---|
73 |
|
---|
74 | To enable event-driven notification of device connection events, first call
|
---|
75 | setUpNotifications() and then connect to the deviceDiscovered() and deviceRemoved()
|
---|
76 | signals. Event-driven behavior is currently available only on Windows and OS X.
|
---|
77 |
|
---|
78 | \b Example
|
---|
79 | \code
|
---|
80 | QextSerialEnumerator* enumerator = new QextSerialEnumerator();
|
---|
81 | connect(enumerator, SIGNAL(deviceDiscovered(const QextPortInfo &)),
|
---|
82 | myClass, SLOT(onDeviceDiscovered(const QextPortInfo &)));
|
---|
83 | connect(enumerator, SIGNAL(deviceRemoved(const QextPortInfo &)),
|
---|
84 | myClass, SLOT(onDeviceRemoved(const QextPortInfo &)));
|
---|
85 | \endcode
|
---|
86 |
|
---|
87 | \section Credits
|
---|
88 | Windows implementation is based on Zach Gorman's work from
|
---|
89 | <a href="http://www.codeproject.com">The Code Project</a> (http://www.codeproject.com/system/setupdi.asp).
|
---|
90 |
|
---|
91 | OS X implementation, see
|
---|
92 | http://developer.apple.com/documentation/DeviceDrivers/Conceptual/AccessingHardware/AH_Finding_Devices/chapter_4_section_2.html
|
---|
93 |
|
---|
94 | \author Michal Policht, Liam Staskawicz
|
---|
95 | */
|
---|
96 | class QEXTSERIALPORT_EXPORT QextSerialEnumerator : public QObject
|
---|
97 | {
|
---|
98 | Q_OBJECT
|
---|
99 | public:
|
---|
100 | QextSerialEnumerator( );
|
---|
101 | ~QextSerialEnumerator( );
|
---|
102 |
|
---|
103 | #ifdef Q_OS_WIN
|
---|
104 | LRESULT onDeviceChangeWin( WPARAM wParam, LPARAM lParam );
|
---|
105 | private:
|
---|
106 | /*!
|
---|
107 | * Get value of specified property from the registry.
|
---|
108 | * \param key handle to an open key.
|
---|
109 | * \param property property name.
|
---|
110 | * \return property value.
|
---|
111 | */
|
---|
112 | static QString getRegKeyValue(HKEY key, LPCTSTR property);
|
---|
113 |
|
---|
114 | /*!
|
---|
115 | * Get specific property from registry.
|
---|
116 | * \param devInfo pointer to the device information set that contains the interface
|
---|
117 | * and its underlying device. Returned by SetupDiGetClassDevs() function.
|
---|
118 | * \param devData pointer to an SP_DEVINFO_DATA structure that defines the device instance.
|
---|
119 | * this is returned by SetupDiGetDeviceInterfaceDetail() function.
|
---|
120 | * \param property registry property. One of defined SPDRP_* constants.
|
---|
121 | * \return property string.
|
---|
122 | */
|
---|
123 | static QString getDeviceProperty(HDEVINFO devInfo, PSP_DEVINFO_DATA devData, DWORD property);
|
---|
124 |
|
---|
125 | /*!
|
---|
126 | * Search for serial ports using setupapi.
|
---|
127 | * \param infoList list with result.
|
---|
128 | */
|
---|
129 | static void setupAPIScan(QList<QextPortInfo> & infoList);
|
---|
130 | void setUpNotificationWin( );
|
---|
131 | static bool getDeviceDetailsWin( QextPortInfo* portInfo, HDEVINFO devInfo,
|
---|
132 | PSP_DEVINFO_DATA devData, WPARAM wParam = DBT_DEVICEARRIVAL );
|
---|
133 | static void enumerateDevicesWin( const GUID & guidDev, QList<QextPortInfo>* infoList );
|
---|
134 | bool matchAndDispatchChangedDevice(const QString & deviceID, const GUID & guid, WPARAM wParam);
|
---|
135 | #ifdef QT_GUI_LIB
|
---|
136 | QextSerialRegistrationWidget* notificationWidget;
|
---|
137 | #endif
|
---|
138 | #endif /*Q_OS_WIN*/
|
---|
139 |
|
---|
140 | #ifdef Q_OS_UNIX
|
---|
141 | #ifdef Q_OS_MAC
|
---|
142 | private:
|
---|
143 | /*!
|
---|
144 | * Search for serial ports using IOKit.
|
---|
145 | * \param infoList list with result.
|
---|
146 | */
|
---|
147 | static void scanPortsOSX(QList<QextPortInfo> & infoList);
|
---|
148 | static void iterateServicesOSX(io_object_t service, QList<QextPortInfo> & infoList);
|
---|
149 | static bool getServiceDetailsOSX( io_object_t service, QextPortInfo* portInfo );
|
---|
150 |
|
---|
151 | void setUpNotificationOSX( );
|
---|
152 | void onDeviceDiscoveredOSX( io_object_t service );
|
---|
153 | void onDeviceTerminatedOSX( io_object_t service );
|
---|
154 | friend void deviceDiscoveredCallbackOSX( void *ctxt, io_iterator_t serialPortIterator );
|
---|
155 | friend void deviceTerminatedCallbackOSX( void *ctxt, io_iterator_t serialPortIterator );
|
---|
156 |
|
---|
157 | IONotificationPortRef notificationPortRef;
|
---|
158 |
|
---|
159 | #else // Q_OS_MAC
|
---|
160 | private:
|
---|
161 | /*!
|
---|
162 | * Search for serial ports on unix.
|
---|
163 | * \param infoList list with result.
|
---|
164 | */
|
---|
165 | static void scanPortsNix(QList<QextPortInfo> & infoList);
|
---|
166 | #endif // Q_OS_MAC
|
---|
167 | #endif /* Q_OS_UNIX */
|
---|
168 |
|
---|
169 | public:
|
---|
170 | /*!
|
---|
171 | Get list of ports.
|
---|
172 | \return list of ports currently available in the system.
|
---|
173 | */
|
---|
174 | static QList<QextPortInfo> getPorts();
|
---|
175 | /*!
|
---|
176 | Enable event-driven notifications of board discovery/removal.
|
---|
177 | */
|
---|
178 | void setUpNotifications( );
|
---|
179 |
|
---|
180 | signals:
|
---|
181 | /*!
|
---|
182 | A new device has been connected to the system.
|
---|
183 |
|
---|
184 | setUpNotifications() must be called first to enable event-driven device notifications.
|
---|
185 | Currently only implemented on Windows and OS X.
|
---|
186 | \param info The device that has been discovered.
|
---|
187 | */
|
---|
188 | void deviceDiscovered( const QextPortInfo & info );
|
---|
189 | /*!
|
---|
190 | A device has been disconnected from the system.
|
---|
191 |
|
---|
192 | setUpNotifications() must be called first to enable event-driven device notifications.
|
---|
193 | Currently only implemented on Windows and OS X.
|
---|
194 | \param info The device that was disconnected.
|
---|
195 | */
|
---|
196 | void deviceRemoved( const QextPortInfo & info );
|
---|
197 | };
|
---|
198 |
|
---|
199 | #endif /*_QEXTSERIALENUMERATOR_H_*/
|
---|