diff --git a/extserial/src/qextserialenumerator.cpp b/extserial/src/qextserialenumerator.cpp deleted file mode 100644 index 9ffd098..0000000 --- a/extserial/src/qextserialenumerator.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/**************************************************************************** -** Copyright (c) 2000-2003 Wayne Roth -** Copyright (c) 2004-2007 Stefan Sander -** Copyright (c) 2007 Michal Policht -** Copyright (c) 2008 Brandon Fosdick -** Copyright (c) 2009-2010 Liam Staskawicz -** Copyright (c) 2011 Debao Zhang -** All right reserved. -** Web: http://code.google.com/p/qextserialport/ -** -** Permission is hereby granted, free of charge, to any person obtaining -** a copy of this software and associated documentation files (the -** "Software"), to deal in the Software without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Software, and to -** permit persons to whom the Software is furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be -** included in all copies or substantial portions of the Software. -** -** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -** -****************************************************************************/ - -#include "qextserialenumerator.h" -#include "qextserialenumerator_p.h" - -#include -#include -#include - -QextSerialEnumeratorPrivate::QextSerialEnumeratorPrivate(QextSerialEnumerator *enumrator) - :q_ptr(enumrator) -{ - init_sys(); -} - -QextSerialEnumeratorPrivate::~QextSerialEnumeratorPrivate() -{ - destroy_sys(); -} - -/*! - \class QextPortInfo - - \brief The QextPortInfo class containing port information. - - Structure containing port information. - - \code - QString portName; ///< Port name. - QString physName; ///< Physical name. - QString friendName; ///< Friendly name. - QString enumName; ///< Enumerator name. - int vendorID; ///< Vendor ID. - int productID; ///< Product ID - \endcode - */ - -/*! \class QextSerialEnumerator - - \brief The QextSerialEnumerator class provides list of ports available in the system. - - \section1 Usage - To poll the system for a list of connected devices, simply use getPorts(). Each - QextPortInfo structure will populated with information about the corresponding device. - - \bold Example - \code - QList ports = QextSerialEnumerator::getPorts(); - foreach (QextPortInfo port, ports) { - // inspect port... - } - \endcode - - To enable event-driven notification of device connection events, first call - setUpNotifications() and then connect to the deviceDiscovered() and deviceRemoved() - signals. Event-driven behavior is currently available only on Windows and OS X. - - \bold Example - \code - QextSerialEnumerator *enumerator = new QextSerialEnumerator(); - connect(enumerator, SIGNAL(deviceDiscovered(const QextPortInfo &)), - myClass, SLOT(onDeviceDiscovered(const QextPortInfo &))); - connect(enumerator, SIGNAL(deviceRemoved(const QextPortInfo &)), - myClass, SLOT(onDeviceRemoved(const QextPortInfo &))); - \endcode - - \section1 Credits - Windows implementation is based on Zach Gorman's work from - \l {http://www.codeproject.com}{The Code Project} (\l http://www.codeproject.com/system/setupdi.asp). - - OS X implementation, see \l http://developer.apple.com/documentation/DeviceDrivers/Conceptual/AccessingHardware/AH_Finding_Devices/chapter_4_section_2.html - - \bold author Michal Policht, Liam Staskawicz -*/ - -/*! - \fn void QextSerialEnumerator::deviceDiscovered(const QextPortInfo &info) - A new device has been connected to the system. - - setUpNotifications() must be called first to enable event-driven device notifications. - Currently only implemented on Windows and OS X. - - \a info The device that has been discovered. -*/ - -/*! - \fn void QextSerialEnumerator::deviceRemoved(const QextPortInfo &info); - A device has been disconnected from the system. - - setUpNotifications() must be called first to enable event-driven device notifications. - Currently only implemented on Windows and OS X. - - \a info The device that was disconnected. -*/ - -/*! - Constructs a QextSerialEnumerator object with the given \a parent. -*/ -QextSerialEnumerator::QextSerialEnumerator(QObject *parent) - :QObject(parent), d_ptr(new QextSerialEnumeratorPrivate(this)) -{ - if (!QMetaType::isRegistered(QMetaType::type("QextPortInfo"))) - qRegisterMetaType("QextPortInfo"); -} - -/*! - Destructs the QextSerialEnumerator object. -*/ -QextSerialEnumerator::~QextSerialEnumerator() -{ - delete d_ptr; -} - -/*! - Get list of ports. - - return list of ports currently available in the system. -*/ -QList QextSerialEnumerator::getPorts() -{ - return QextSerialEnumeratorPrivate::getPorts_sys(); -} - -/*! - Enable event-driven notifications of board discovery/removal. -*/ -void QextSerialEnumerator::setUpNotifications() -{ - Q_D(QextSerialEnumerator); - if (!d->setUpNotifications_sys(true)) - QESP_WARNING("Setup Notification Failed..."); -} - -#include "moc_qextserialenumerator.cpp" diff --git a/extserial/src/qextserialenumerator.h b/extserial/src/qextserialenumerator.h deleted file mode 100644 index f207d0d..0000000 --- a/extserial/src/qextserialenumerator.h +++ /dev/null @@ -1,72 +0,0 @@ -/**************************************************************************** -** Copyright (c) 2000-2003 Wayne Roth -** Copyright (c) 2004-2007 Stefan Sander -** Copyright (c) 2007 Michal Policht -** Copyright (c) 2008 Brandon Fosdick -** Copyright (c) 2009-2010 Liam Staskawicz -** Copyright (c) 2011 Debao Zhang -** All right reserved. -** Web: http://code.google.com/p/qextserialport/ -** -** Permission is hereby granted, free of charge, to any person obtaining -** a copy of this software and associated documentation files (the -** "Software"), to deal in the Software without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Software, and to -** permit persons to whom the Software is furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be -** included in all copies or substantial portions of the Software. -** -** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -** -****************************************************************************/ - -#ifndef _QEXTSERIALENUMERATOR_H_ -#define _QEXTSERIALENUMERATOR_H_ - -#include -#include -#include "qextserialport_global.h" - -struct QextPortInfo { - QString portName; ///< Port name. - QString physName; ///< Physical name. - QString friendName; ///< Friendly name. - QString enumName; ///< Enumerator name. - int vendorID; ///< Vendor ID. - int productID; ///< Product ID -}; - -class QextSerialEnumeratorPrivate; -class QEXTSERIALPORT_EXPORT QextSerialEnumerator : public QObject -{ - Q_OBJECT - Q_DECLARE_PRIVATE(QextSerialEnumerator) -public: - QextSerialEnumerator(QObject *parent=0); - ~QextSerialEnumerator(); - - static QList getPorts(); - void setUpNotifications(); - -Q_SIGNALS: - void deviceDiscovered(const QextPortInfo &info); - void deviceRemoved(const QextPortInfo &info); - -private: - Q_DISABLE_COPY(QextSerialEnumerator) -#if defined(Q_OS_LINUX) && !defined(QESP_NO_UDEV) - Q_PRIVATE_SLOT(d_func(), void _q_deviceEvent()) -#endif - QextSerialEnumeratorPrivate *d_ptr; -}; - -#endif /*_QEXTSERIALENUMERATOR_H_*/ diff --git a/extserial/src/qextserialenumerator_linux.cpp b/extserial/src/qextserialenumerator_linux.cpp deleted file mode 100644 index 450d883..0000000 --- a/extserial/src/qextserialenumerator_linux.cpp +++ /dev/null @@ -1,210 +0,0 @@ -/**************************************************************************** -** Copyright (c) 2000-2003 Wayne Roth -** Copyright (c) 2004-2007 Stefan Sander -** Copyright (c) 2007 Michal Policht -** Copyright (c) 2008 Brandon Fosdick -** Copyright (c) 2009-2010 Liam Staskawicz -** Copyright (c) 2011 Debao Zhang -** Copyright (c) 2012 Doug Brown -** All right reserved. -** Web: http://code.google.com/p/qextserialport/ -** -** Permission is hereby granted, free of charge, to any person obtaining -** a copy of this software and associated documentation files (the -** "Software"), to deal in the Software without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Software, and to -** permit persons to whom the Software is furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be -** included in all copies or substantial portions of the Software. -** -** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -** -****************************************************************************/ - -#include "qextserialenumerator.h" -#include "qextserialenumerator_p.h" -#include -#include -#include - -void QextSerialEnumeratorPrivate::init_sys() -{ -#ifndef QESP_NO_UDEV - monitor = NULL; - notifierFd = -1; - notifier = NULL; - - udev = udev_new(); - if (!udev) - qCritical() << "Unable to initialize udev notifications"; -#endif -} - -void QextSerialEnumeratorPrivate::destroy_sys() -{ -#ifndef QESP_NO_UDEV - if (notifier) { - notifier->setEnabled(false); - delete notifier; - } - - if (monitor) - udev_monitor_unref(monitor); - - if (udev) - udev_unref(udev); -#endif -} - -#ifndef QESP_NO_UDEV -static QextPortInfo portInfoFromDevice(struct udev_device *dev) -{ - QString vendor = QString::fromLatin1(udev_device_get_property_value(dev, "ID_VENDOR_ID")); - QString product = QString::fromLatin1(udev_device_get_property_value(dev, "ID_MODEL_ID")); - - QextPortInfo pi; - pi.vendorID = vendor.toInt(0, 16); - pi.productID = product.toInt(0, 16); - pi.portName = QString::fromLatin1(udev_device_get_devnode(dev)); - pi.physName = pi.portName; - - return pi; -} -#endif - -QList QextSerialEnumeratorPrivate::getPorts_sys() -{ - QList infoList; -#ifndef QESP_NO_UDEV - struct udev *ud = udev_new(); - if (!ud) { - qCritical() << "Unable to enumerate ports because udev is not initialized."; - return infoList; - } - - struct udev_enumerate *enumerate = udev_enumerate_new(ud); - udev_enumerate_add_match_subsystem(enumerate, "tty"); - udev_enumerate_scan_devices(enumerate); - struct udev_list_entry *list = udev_enumerate_get_list_entry(enumerate); - struct udev_list_entry *entry; - udev_list_entry_foreach(entry, list) { - const char *path; - struct udev_device *dev; - - // Have to grab the actual udev device here... - path = udev_list_entry_get_name(entry); - dev = udev_device_new_from_syspath(ud, path); - - infoList.append(portInfoFromDevice(dev)); - - // Done with this device - udev_device_unref(dev); - } - // Done with the list and this udev - udev_enumerate_unref(enumerate); - udev_unref(ud); -#else - QStringList portNamePrefixes, portNameList; - portNamePrefixes << QLatin1String("ttyS*"); // list normal serial ports first - - QDir dir(QLatin1String("/dev")); - portNameList = dir.entryList(portNamePrefixes, (QDir::System | QDir::Files), QDir::Name); - - // remove the values which are not serial ports for e.g. /dev/ttysa - for (int i = 0; i < portNameList.size(); i++) { - bool ok; - QString current = portNameList.at(i); - // remove the ttyS part, and check, if the other part is a number - current.remove(0,4).toInt(&ok, 10); - if (!ok) { - portNameList.removeAt(i); - i--; - } - } - - // get the non standard serial ports names - // (USB-serial, bluetooth-serial, 18F PICs, and so on) - // if you know an other name prefix for serial ports please let us know - portNamePrefixes.clear(); - portNamePrefixes << QLatin1String("ttyACM*") << QLatin1String("ttyUSB*") << QLatin1String("rfcomm*"); - portNameList += dir.entryList(portNamePrefixes, (QDir::System | QDir::Files), QDir::Name); - - foreach (QString str , portNameList) { - QextPortInfo inf; - inf.physName = QLatin1String("/dev/")+str; - inf.portName = str; - - if (str.contains(QLatin1String("ttyS"))) { - inf.friendName = QLatin1String("Serial port ")+str.remove(0, 4); - } - else if (str.contains(QLatin1String("ttyUSB"))) { - inf.friendName = QLatin1String("USB-serial adapter ")+str.remove(0, 6); - } - else if (str.contains(QLatin1String("rfcomm"))) { - inf.friendName = QLatin1String("Bluetooth-serial adapter ")+str.remove(0, 6); - } - inf.enumName = QLatin1String("/dev"); // is there a more helpful name for this? - infoList.append(inf); - } -#endif - - return infoList; -} - -bool QextSerialEnumeratorPrivate::setUpNotifications_sys(bool setup) -{ - Q_UNUSED(setup); -#ifndef QESP_NO_UDEV - Q_Q(QextSerialEnumerator); - if (!udev) { - qCritical() << "Unable to initialize notifications because udev is not initialized."; - return false; - } - - // Emit signals immediately for devices already connected (Windows version seems to behave - // this way) - foreach (QextPortInfo i, getPorts_sys()) - Q_EMIT q->deviceDiscovered(i); - - // Look for tty devices from udev. - monitor = udev_monitor_new_from_netlink(udev, "udev"); - udev_monitor_filter_add_match_subsystem_devtype(monitor, "tty", NULL); - udev_monitor_enable_receiving(monitor); - notifierFd = udev_monitor_get_fd(monitor); - notifier = new QSocketNotifier(notifierFd, QSocketNotifier::Read); - q->connect(notifier, SIGNAL(activated(int)), q, SLOT(_q_deviceEvent())); - notifier->setEnabled(true); - - return true; -#else - return false; -#endif -} - -#ifndef QESP_NO_UDEV -void QextSerialEnumeratorPrivate::_q_deviceEvent() -{ - Q_Q(QextSerialEnumerator); - struct udev_device *dev = udev_monitor_receive_device(monitor); - if (dev) { - QextPortInfo pi = portInfoFromDevice(dev); - QLatin1String action(udev_device_get_action(dev)); - - if (action == QLatin1String("add")) - Q_EMIT q->deviceDiscovered(pi); - else if (action == QLatin1String("remove")) - Q_EMIT q->deviceRemoved(pi); - - udev_device_unref(dev); - } -} -#endif diff --git a/extserial/src/qextserialenumerator_osx.cpp b/extserial/src/qextserialenumerator_osx.cpp deleted file mode 100644 index ad33e9a..0000000 --- a/extserial/src/qextserialenumerator_osx.cpp +++ /dev/null @@ -1,307 +0,0 @@ -/**************************************************************************** -** Copyright (c) 2000-2003 Wayne Roth -** Copyright (c) 2004-2007 Stefan Sander -** Copyright (c) 2007 Michal Policht -** Copyright (c) 2008 Brandon Fosdick -** Copyright (c) 2009-2010 Liam Staskawicz -** Copyright (c) 2011 Debao Zhang -** All right reserved. -** Web: http://code.google.com/p/qextserialport/ -** -** Permission is hereby granted, free of charge, to any person obtaining -** a copy of this software and associated documentation files (the -** "Software"), to deal in the Software without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Software, and to -** permit persons to whom the Software is furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be -** included in all copies or substantial portions of the Software. -** -** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -** -****************************************************************************/ - -#include "qextserialenumerator.h" -#include "qextserialenumerator_p.h" -#include -#include -#include -#include - -void QextSerialEnumeratorPrivate::init_sys() -{ -} - -void QextSerialEnumeratorPrivate::destroy_sys() -{ - IONotificationPortDestroy(notificationPortRef); -} - -// static -QList QextSerialEnumeratorPrivate::getPorts_sys() -{ - QList infoList; - io_iterator_t serialPortIterator = 0; - kern_return_t kernResult = KERN_FAILURE; - CFMutableDictionaryRef matchingDictionary; - - // first try to get any serialbsd devices, then try any USBCDC devices - if (!(matchingDictionary = IOServiceMatching(kIOSerialBSDServiceValue))) { - QESP_WARNING("IOServiceMatching returned a NULL dictionary."); - return infoList; - } - CFDictionaryAddValue(matchingDictionary, CFSTR(kIOSerialBSDTypeKey), CFSTR(kIOSerialBSDAllTypes)); - - // then create the iterator with all the matching devices - if (IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDictionary, &serialPortIterator) != KERN_SUCCESS) { - qCritical() << "IOServiceGetMatchingServices failed, returned" << kernResult; - return infoList; - } - iterateServicesOSX(serialPortIterator, infoList); - IOObjectRelease(serialPortIterator); - serialPortIterator = 0; - - if (!(matchingDictionary = IOServiceNameMatching("AppleUSBCDC"))) { - QESP_WARNING("IOServiceNameMatching returned a NULL dictionary."); - return infoList; - } - - if (IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDictionary, &serialPortIterator) != KERN_SUCCESS) { - qCritical() << "IOServiceGetMatchingServices failed, returned" << kernResult; - return infoList; - } - iterateServicesOSX(serialPortIterator, infoList); - IOObjectRelease(serialPortIterator); - - return infoList; -} - -void QextSerialEnumeratorPrivate::iterateServicesOSX(io_object_t service, QList &infoList) -{ - // Iterate through all modems found. - io_object_t usbService; - while ((usbService = IOIteratorNext(service))) { - QextPortInfo info; - info.vendorID = 0; - info.productID = 0; - getServiceDetailsOSX(usbService, &info); - infoList.append(info); - } -} - -bool QextSerialEnumeratorPrivate::getServiceDetailsOSX(io_object_t service, QextPortInfo *portInfo) -{ - bool retval = true; - CFTypeRef bsdPathAsCFString = NULL; - CFTypeRef productNameAsCFString = NULL; - CFTypeRef vendorIdAsCFNumber = NULL; - CFTypeRef productIdAsCFNumber = NULL; - // check the name of the modem's callout device - bsdPathAsCFString = IORegistryEntryCreateCFProperty(service, CFSTR(kIOCalloutDeviceKey), - kCFAllocatorDefault, 0); - - // wander up the hierarchy until we find the level that can give us the - // vendor/product IDs and the product name, if available - io_registry_entry_t parent; - kern_return_t kernResult = IORegistryEntryGetParentEntry(service, kIOServicePlane, &parent); - while (kernResult == KERN_SUCCESS && !vendorIdAsCFNumber && !productIdAsCFNumber) { - if (!productNameAsCFString) - productNameAsCFString = IORegistryEntrySearchCFProperty(parent, - kIOServicePlane, - CFSTR("Product Name"), - kCFAllocatorDefault, 0); - vendorIdAsCFNumber = IORegistryEntrySearchCFProperty(parent, - kIOServicePlane, - CFSTR(kUSBVendorID), - kCFAllocatorDefault, 0); - productIdAsCFNumber = IORegistryEntrySearchCFProperty(parent, - kIOServicePlane, - CFSTR(kUSBProductID), - kCFAllocatorDefault, 0); - io_registry_entry_t oldparent = parent; - kernResult = IORegistryEntryGetParentEntry(parent, kIOServicePlane, &parent); - IOObjectRelease(oldparent); - } - - io_string_t ioPathName; - IORegistryEntryGetPath(service, kIOServicePlane, ioPathName); - portInfo->physName = ioPathName; - - if (bsdPathAsCFString) { - char path[MAXPATHLEN]; - if (CFStringGetCString((CFStringRef)bsdPathAsCFString, path, - PATH_MAX, kCFStringEncodingUTF8)) - portInfo->portName = path; - CFRelease(bsdPathAsCFString); - } - - if (productNameAsCFString) { - char productName[MAXPATHLEN]; - if (CFStringGetCString((CFStringRef)productNameAsCFString, productName, - PATH_MAX, kCFStringEncodingUTF8)) - portInfo->friendName = productName; - CFRelease(productNameAsCFString); - } - - if (vendorIdAsCFNumber) { - SInt32 vID; - if (CFNumberGetValue((CFNumberRef)vendorIdAsCFNumber, kCFNumberSInt32Type, &vID)) - portInfo->vendorID = vID; - CFRelease(vendorIdAsCFNumber); - } - - if (productIdAsCFNumber) { - SInt32 pID; - if (CFNumberGetValue((CFNumberRef)productIdAsCFNumber, kCFNumberSInt32Type, &pID)) - portInfo->productID = pID; - CFRelease(productIdAsCFNumber); - } - IOObjectRelease(service); - return retval; -} - -// IOKit callbacks registered via setupNotifications() -void deviceDiscoveredCallbackOSX(void *ctxt, io_iterator_t serialPortIterator) -{ - QextSerialEnumeratorPrivate *d = (QextSerialEnumeratorPrivate *)ctxt; - io_object_t serialService; - while ((serialService = IOIteratorNext(serialPortIterator))) - d->onDeviceDiscoveredOSX(serialService); -} - -void deviceTerminatedCallbackOSX(void *ctxt, io_iterator_t serialPortIterator) -{ - QextSerialEnumeratorPrivate *d = (QextSerialEnumeratorPrivate *)ctxt; - io_object_t serialService; - while ((serialService = IOIteratorNext(serialPortIterator))) - d->onDeviceTerminatedOSX(serialService); -} - -/* - A device has been discovered via IOKit. - Create a QextPortInfo if possible, and emit the signal indicating that we've found it. -*/ -void QextSerialEnumeratorPrivate::onDeviceDiscoveredOSX(io_object_t service) -{ - Q_Q(QextSerialEnumerator); - QextPortInfo info; - info.vendorID = 0; - info.productID = 0; - if (getServiceDetailsOSX(service, &info)) - Q_EMIT q->deviceDiscovered(info); -} - -/* - Notification via IOKit that a device has been removed. - Create a QextPortInfo if possible, and emit the signal indicating that it's gone. -*/ -void QextSerialEnumeratorPrivate::onDeviceTerminatedOSX(io_object_t service) -{ - Q_Q(QextSerialEnumerator); - QextPortInfo info; - info.vendorID = 0; - info.productID = 0; - if (getServiceDetailsOSX(service, &info)) - Q_EMIT q->deviceRemoved(info); -} - -/* - Create matching dictionaries for the devices we want to get notifications for, - and add them to the current run loop. Invoke the callbacks that will be responding - to these notifications once to arm them, and discover any devices that - are currently connected at the time notifications are setup. -*/ -bool QextSerialEnumeratorPrivate::setUpNotifications_sys(bool /*setup*/) -{ - kern_return_t kernResult; - mach_port_t masterPort; - CFRunLoopSourceRef notificationRunLoopSource; - CFMutableDictionaryRef classesToMatch; - CFMutableDictionaryRef cdcClassesToMatch; - io_iterator_t portIterator; - - kernResult = IOMasterPort(MACH_PORT_NULL, &masterPort); - if (KERN_SUCCESS != kernResult) { - qDebug() << "IOMasterPort returned:" << kernResult; - return false; - } - - classesToMatch = IOServiceMatching(kIOSerialBSDServiceValue); - if (classesToMatch == NULL) - qDebug("IOServiceMatching returned a NULL dictionary."); - else - CFDictionarySetValue(classesToMatch, CFSTR(kIOSerialBSDTypeKey), CFSTR(kIOSerialBSDAllTypes)); - - if (!(cdcClassesToMatch = IOServiceNameMatching("AppleUSBCDC"))) { - QESP_WARNING("couldn't create cdc matching dict"); - return false; - } - - // Retain an additional reference since each call to IOServiceAddMatchingNotification consumes one. - classesToMatch = (CFMutableDictionaryRef) CFRetain(classesToMatch); - cdcClassesToMatch = (CFMutableDictionaryRef) CFRetain(cdcClassesToMatch); - - notificationPortRef = IONotificationPortCreate(masterPort); - if (notificationPortRef == NULL) { - qDebug("IONotificationPortCreate return a NULL IONotificationPortRef."); - return false; - } - - notificationRunLoopSource = IONotificationPortGetRunLoopSource(notificationPortRef); - if (notificationRunLoopSource == NULL) { - qDebug("IONotificationPortGetRunLoopSource returned NULL CFRunLoopSourceRef."); - return false; - } - - CFRunLoopAddSource(CFRunLoopGetCurrent(), notificationRunLoopSource, kCFRunLoopDefaultMode); - - kernResult = IOServiceAddMatchingNotification(notificationPortRef, kIOMatchedNotification, classesToMatch, - deviceDiscoveredCallbackOSX, this, &portIterator); - if (kernResult != KERN_SUCCESS) { - qDebug() << "IOServiceAddMatchingNotification return:" << kernResult; - return false; - } - - // arm the callback, and grab any devices that are already connected - deviceDiscoveredCallbackOSX(this, portIterator); - - kernResult = IOServiceAddMatchingNotification(notificationPortRef, kIOMatchedNotification, cdcClassesToMatch, - deviceDiscoveredCallbackOSX, this, &portIterator); - if (kernResult != KERN_SUCCESS) { - qDebug() << "IOServiceAddMatchingNotification return:" << kernResult; - return false; - } - - // arm the callback, and grab any devices that are already connected - deviceDiscoveredCallbackOSX(this, portIterator); - - kernResult = IOServiceAddMatchingNotification(notificationPortRef, kIOTerminatedNotification, classesToMatch, - deviceTerminatedCallbackOSX, this, &portIterator); - if (kernResult != KERN_SUCCESS) { - qDebug() << "IOServiceAddMatchingNotification return:" << kernResult; - return false; - } - - // arm the callback, and clear any devices that are terminated - deviceTerminatedCallbackOSX(this, portIterator); - - kernResult = IOServiceAddMatchingNotification(notificationPortRef, kIOTerminatedNotification, cdcClassesToMatch, - deviceTerminatedCallbackOSX, this, &portIterator); - if (kernResult != KERN_SUCCESS) { - qDebug() << "IOServiceAddMatchingNotification return:" << kernResult; - return false; - } - - // arm the callback, and clear any devices that are terminated - deviceTerminatedCallbackOSX(this, portIterator); - return true; -} - diff --git a/extserial/src/qextserialenumerator_p.h b/extserial/src/qextserialenumerator_p.h deleted file mode 100644 index 74bbeb2..0000000 --- a/extserial/src/qextserialenumerator_p.h +++ /dev/null @@ -1,123 +0,0 @@ -/**************************************************************************** -** Copyright (c) 2000-2003 Wayne Roth -** Copyright (c) 2004-2007 Stefan Sander -** Copyright (c) 2007 Michal Policht -** Copyright (c) 2008 Brandon Fosdick -** Copyright (c) 2009-2010 Liam Staskawicz -** Copyright (c) 2011 Debao Zhang -** Copyright (c) 2012 Doug Brown -** All right reserved. -** Web: http://code.google.com/p/qextserialport/ -** -** Permission is hereby granted, free of charge, to any person obtaining -** a copy of this software and associated documentation files (the -** "Software"), to deal in the Software without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Software, and to -** permit persons to whom the Software is furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be -** included in all copies or substantial portions of the Software. -** -** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -** -****************************************************************************/ -#ifndef _QEXTSERIALENUMERATOR_P_H_ -#define _QEXTSERIALENUMERATOR_P_H_ - -// -// W A R N I N G -// ------------- -// -// This file is not part of the QESP API. It exists for the convenience -// of other QESP classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qextserialenumerator.h" - -#ifdef Q_CC_MINGW -// needed for mingw to pull in appropriate dbt business... -// probably a better way to do this -// http://mingw-users.1079350.n2.nabble.com/DEV-BROADCAST-DEVICEINTERFACE-was-not-declared-in-this-scope-td3552762.html -// http://msdn.microsoft.com/en-us/library/6sehtctf.aspx -# ifndef WINVER -# define WINVER 0x0501 -# endif -# ifndef _WIN32_WINNT -# define _WIN32_WINNT WINVER -# endif -#endif - -#ifdef Q_OS_WIN -# include -#endif /*Q_OS_WIN*/ - -#ifdef Q_OS_MAC -# include -#endif /*Q_OS_MAC*/ - -#if defined(Q_OS_LINUX) && !defined(QESP_NO_UDEV) -# include -extern "C" { -# include -} -#endif - -class QextSerialRegistrationWidget; -class QextSerialEnumeratorPrivate -{ - Q_DECLARE_PUBLIC(QextSerialEnumerator) -public: - QextSerialEnumeratorPrivate(QextSerialEnumerator *enumrator); - ~QextSerialEnumeratorPrivate(); - void init_sys(); - void destroy_sys(); - - static QList getPorts_sys(); - bool setUpNotifications_sys(bool setup); - -#if defined(Q_OS_WIN) && defined(QT_GUI_LIB) - LRESULT onDeviceChanged(WPARAM wParam, LPARAM lParam); - bool matchAndDispatchChangedDevice(const QString &deviceID, const GUID &guid, WPARAM wParam); - QextSerialRegistrationWidget *notificationWidget; -#endif /*Q_OS_WIN*/ - -#ifdef Q_OS_MAC - /*! - * Search for serial ports using IOKit. - * \param infoList list with result. - */ - static void iterateServicesOSX(io_object_t service, QList &infoList); - static bool getServiceDetailsOSX(io_object_t service, QextPortInfo *portInfo); - void onDeviceDiscoveredOSX(io_object_t service); - void onDeviceTerminatedOSX(io_object_t service); - friend void deviceDiscoveredCallbackOSX(void *ctxt, io_iterator_t serialPortIterator); - friend void deviceTerminatedCallbackOSX(void *ctxt, io_iterator_t serialPortIterator); - - IONotificationPortRef notificationPortRef; -#endif // Q_OS_MAC - -#if defined(Q_OS_LINUX) && !defined(QESP_NO_UDEV) - QSocketNotifier *notifier; - int notifierFd; - struct udev *udev; - struct udev_monitor *monitor; - - void _q_deviceEvent(); -#endif - -private: - QextSerialEnumerator *q_ptr; -}; - -#endif //_QEXTSERIALENUMERATOR_P_H_ diff --git a/extserial/src/qextserialenumerator_unix.cpp b/extserial/src/qextserialenumerator_unix.cpp deleted file mode 100644 index dfc12a8..0000000 --- a/extserial/src/qextserialenumerator_unix.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/**************************************************************************** -** Copyright (c) 2000-2003 Wayne Roth -** Copyright (c) 2004-2007 Stefan Sander -** Copyright (c) 2007 Michal Policht -** Copyright (c) 2008 Brandon Fosdick -** Copyright (c) 2009-2010 Liam Staskawicz -** Copyright (c) 2011 Debao Zhang -** All right reserved. -** Web: http://code.google.com/p/qextserialport/ -** -** Permission is hereby granted, free of charge, to any person obtaining -** a copy of this software and associated documentation files (the -** "Software"), to deal in the Software without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Software, and to -** permit persons to whom the Software is furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be -** included in all copies or substantial portions of the Software. -** -** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -** -****************************************************************************/ - -#include "qextserialenumerator.h" -#include "qextserialenumerator_p.h" -#include - -void QextSerialEnumeratorPrivate::init_sys() -{ -} - -void QextSerialEnumeratorPrivate::destroy_sys() -{ -} - -QList QextSerialEnumeratorPrivate::getPorts_sys() -{ - QList infoList; - QESP_WARNING("Enumeration for POSIX systems (except Linux) is not implemented yet."); - return infoList; -} - -bool QextSerialEnumeratorPrivate::setUpNotifications_sys(bool setup) -{ - Q_UNUSED(setup) - QESP_WARNING("Notifications for *Nix/FreeBSD are not implemented yet"); - return false; -} diff --git a/extserial/src/qextserialenumerator_win.cpp b/extserial/src/qextserialenumerator_win.cpp deleted file mode 100644 index d9ed833..0000000 --- a/extserial/src/qextserialenumerator_win.cpp +++ /dev/null @@ -1,303 +0,0 @@ -/**************************************************************************** -** Copyright (c) 2000-2003 Wayne Roth -** Copyright (c) 2004-2007 Stefan Sander -** Copyright (c) 2007 Michal Policht -** Copyright (c) 2008 Brandon Fosdick -** Copyright (c) 2009-2010 Liam Staskawicz -** Copyright (c) 2011 Debao Zhang -** All right reserved. -** Web: http://code.google.com/p/qextserialport/ -** -** Permission is hereby granted, free of charge, to any person obtaining -** a copy of this software and associated documentation files (the -** "Software"), to deal in the Software without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Software, and to -** permit persons to whom the Software is furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be -** included in all copies or substantial portions of the Software. -** -** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -** -****************************************************************************/ - -#include "qextserialenumerator.h" -#include "qextserialenumerator_p.h" -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef QT_GUI_LIB -/*! - \internal - \class QextSerialRegistrationWidget - - Internal window which is used to receive device arrvial and removal message. -*/ - -#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) -#include -class QextSerialRegistrationWidget : public QWidget -#else -#include -class QextSerialRegistrationWidget : public QWindow -#endif -{ -public: - QextSerialRegistrationWidget(QextSerialEnumeratorPrivate *qese) { - this->qese = qese; - } - ~QextSerialRegistrationWidget() {} - -protected: - -#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) - bool winEvent(MSG *message, long *result) { -#else - bool nativeEvent(const QByteArray & /*eventType*/, void *msg, long *result) { - MSG *message = static_cast(msg); -#endif - if (message->message == WM_DEVICECHANGE) { - qese->onDeviceChanged(message->wParam, message->lParam); - *result = 1; - return true; - } - return false; - } -private: - QextSerialEnumeratorPrivate *qese; -}; -#endif // QT_GUI_LIB - -void QextSerialEnumeratorPrivate::init_sys() -{ -#ifdef QT_GUI_LIB - notificationWidget = 0; -#endif // QT_GUI_LIB -} - -/*! - default -*/ -void QextSerialEnumeratorPrivate::destroy_sys() -{ -#ifdef QT_GUI_LIB - if (notificationWidget) - delete notificationWidget; -#endif -} - -#ifndef GUID_DEVINTERFACE_COMPORT -DEFINE_GUID(GUID_DEVINTERFACE_COMPORT, 0x86e0d1e0L, 0x8089, 0x11d0, 0x9c, 0xe4, 0x08, 0x00, 0x3e, 0x30, 0x1f, 0x73); -#endif - - -/*! - \internal - Get value of specified property from the registry. - \a key handle to an open key. - \a property property name. - - return property value. -*/ -static QString getRegKeyValue(HKEY key, LPCTSTR property) -{ - DWORD size = 0; - DWORD type; - if (::RegQueryValueEx(key, property, NULL, NULL, NULL, &size) != ERROR_SUCCESS) - return QString(); - BYTE *buff = new BYTE[size]; - QString result; - if (::RegQueryValueEx(key, property, NULL, &type, buff, &size) == ERROR_SUCCESS) - result = QString::fromUtf16(reinterpret_cast(buff)); - delete [] buff; - return result; -} - -/*! - \internal - Get specific property from registry. - \a devInfoSet pointer to the device information set that contains the interface - and its underlying device. Returned by SetupDiGetClassDevs() function. - \a devInfoData pointer to an SP_DEVINFO_DATA structure that defines the device instance. - this is returned by SetupDiGetDeviceInterfaceDetail() function. - \a property registry property. One of defined SPDRP_* constants. - - return property string. - */ -static QString getDeviceRegistryProperty(HDEVINFO devInfoSet, PSP_DEVINFO_DATA devInfoData, DWORD property) -{ - DWORD buffSize = 0; - ::SetupDiGetDeviceRegistryProperty(devInfoSet, devInfoData, property, NULL, NULL, 0, &buffSize); - if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) - return QString(); - BYTE *buff = new BYTE[buffSize]; - ::SetupDiGetDeviceRegistryProperty(devInfoSet, devInfoData, property, NULL, buff, buffSize, NULL); - QString result = QString::fromUtf16(reinterpret_cast(buff)); - delete [] buff; - return result; -} - -/*! - \internal -*/ -static bool getDeviceDetailsInformation(QextPortInfo *portInfo, HDEVINFO devInfoSet, PSP_DEVINFO_DATA devInfoData - , WPARAM wParam = DBT_DEVICEARRIVAL) -{ - portInfo->friendName = getDeviceRegistryProperty(devInfoSet, devInfoData, SPDRP_FRIENDLYNAME); - if (wParam == DBT_DEVICEARRIVAL) - portInfo->physName = getDeviceRegistryProperty(devInfoSet, devInfoData, SPDRP_PHYSICAL_DEVICE_OBJECT_NAME); - portInfo->enumName = getDeviceRegistryProperty(devInfoSet, devInfoData, SPDRP_ENUMERATOR_NAME); - - HKEY devKey = ::SetupDiOpenDevRegKey(devInfoSet, devInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_QUERY_VALUE); - portInfo->portName = getRegKeyValue(devKey, TEXT("PortName")); - ::RegCloseKey(devKey); - - QString hardwareIDs = getDeviceRegistryProperty(devInfoSet, devInfoData, SPDRP_HARDWAREID); - QRegExp idRx(QLatin1String("VID_(\\w+)&PID_(\\w+)")); - if (hardwareIDs.toUpper().contains(idRx)) { - bool dummy; - portInfo->vendorID = idRx.cap(1).toInt(&dummy, 16); - portInfo->productID = idRx.cap(2).toInt(&dummy, 16); - //qDebug() << "got vid:" << vid << "pid:" << pid; - } - return true; -} - -/*! - \internal -*/ -static void enumerateDevices(const GUID &guid, QList *infoList) -{ - HDEVINFO devInfoSet = ::SetupDiGetClassDevs(&guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); - if (devInfoSet != INVALID_HANDLE_VALUE) { - SP_DEVINFO_DATA devInfoData; - devInfoData.cbSize = sizeof(SP_DEVINFO_DATA); - for(int i = 0; ::SetupDiEnumDeviceInfo(devInfoSet, i, &devInfoData); i++) { - QextPortInfo info; - info.productID = info.vendorID = 0; - getDeviceDetailsInformation(&info, devInfoSet, &devInfoData); - infoList->append(info); - } - ::SetupDiDestroyDeviceInfoList(devInfoSet); - } -} - - -static bool lessThan(const QextPortInfo &s1, const QextPortInfo &s2) -{ - if (s1.portName.startsWith(QLatin1String("COM")) - && s2.portName.startsWith(QLatin1String("COM"))) { - return s1.portName.mid(3).toInt() QextSerialEnumeratorPrivate::getPorts_sys() -{ - QList ports; - enumerateDevices(GUID_DEVINTERFACE_COMPORT, &ports); - std::sort(ports.begin(), ports.end(), lessThan); - return ports; -} - - -/* - Enable event-driven notifications of board discovery/removal. -*/ -bool QextSerialEnumeratorPrivate::setUpNotifications_sys(bool setup) -{ -#ifndef QT_GUI_LIB - Q_UNUSED(setup) - QESP_WARNING("QextSerialEnumerator: GUI not enabled - can't register for device notifications."); - return false; -#else - Q_Q(QextSerialEnumerator); - if (setup && notificationWidget) //already setup - return true; - notificationWidget = new QextSerialRegistrationWidget(this); - - DEV_BROADCAST_DEVICEINTERFACE dbh; - ::ZeroMemory(&dbh, sizeof(dbh)); - dbh.dbcc_size = sizeof(dbh); - dbh.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; - // dbh.dbcc_classguid = GUID_DEVCLASS_PORTS; //Ignored in such case - DWORD flags = DEVICE_NOTIFY_WINDOW_HANDLE|DEVICE_NOTIFY_ALL_INTERFACE_CLASSES; - if (::RegisterDeviceNotification((HWND)notificationWidget->winId(), &dbh, flags) == NULL) { - QESP_WARNING() << "RegisterDeviceNotification failed:" << GetLastError(); - return false; - } - // setting up notifications doesn't tell us about devices already connected - // so get those manually - foreach (QextPortInfo port, getPorts_sys()) - Q_EMIT q->deviceDiscovered(port); - return true; -#endif // QT_GUI_LIB -} - -#ifdef QT_GUI_LIB -LRESULT QextSerialEnumeratorPrivate::onDeviceChanged(WPARAM wParam, LPARAM lParam) -{ - if (DBT_DEVICEARRIVAL == wParam || DBT_DEVICEREMOVECOMPLETE == wParam) { - PDEV_BROADCAST_HDR pHdr = (PDEV_BROADCAST_HDR)lParam; - if (pHdr->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) { - PDEV_BROADCAST_DEVICEINTERFACE pDevInf = (PDEV_BROADCAST_DEVICEINTERFACE)pHdr; - // delimiters are different across APIs...change to backslash. ugh. - QString deviceID = QString::fromUtf16(reinterpret_cast(pDevInf->dbcc_name)); - deviceID = deviceID.toUpper().replace(QLatin1String("#"), QLatin1String("\\")); - - matchAndDispatchChangedDevice(deviceID, GUID_DEVINTERFACE_COMPORT, wParam); - } - } - return 0; -} - -bool QextSerialEnumeratorPrivate::matchAndDispatchChangedDevice(const QString &deviceID, const GUID &guid, WPARAM wParam) -{ - Q_Q(QextSerialEnumerator); - bool rv = false; - DWORD dwFlag = (DBT_DEVICEARRIVAL == wParam) ? DIGCF_PRESENT : DIGCF_PROFILE; - HDEVINFO devInfoSet = SetupDiGetClassDevs(&guid, NULL, NULL, dwFlag | DIGCF_DEVICEINTERFACE); - if (devInfoSet != INVALID_HANDLE_VALUE) { - SP_DEVINFO_DATA spDevInfoData; - spDevInfoData.cbSize = sizeof(SP_DEVINFO_DATA); - for(int i=0; SetupDiEnumDeviceInfo(devInfoSet, i, &spDevInfoData); i++) { - DWORD nSize = 0; - TCHAR buf[MAX_PATH]; - if (SetupDiGetDeviceInstanceId(devInfoSet, &spDevInfoData, buf, MAX_PATH, &nSize) - && deviceID.contains(QString::fromUtf16(reinterpret_cast(buf)))) { // we found a match - rv = true; - QextPortInfo info; - info.productID = info.vendorID = 0; - getDeviceDetailsInformation(&info, devInfoSet, &spDevInfoData, wParam); - if (wParam == DBT_DEVICEARRIVAL) - Q_EMIT q->deviceDiscovered(info); - else if (wParam == DBT_DEVICEREMOVECOMPLETE) - Q_EMIT q->deviceRemoved(info); - break; - } - } - SetupDiDestroyDeviceInfoList(devInfoSet); - } - return rv; -} -#endif //QT_GUI_LIB diff --git a/extserial/src/qextserialport.cmake b/extserial/src/qextserialport.cmake deleted file mode 100644 index 5e68369..0000000 --- a/extserial/src/qextserialport.cmake +++ /dev/null @@ -1,50 +0,0 @@ -cmake_minimum_required(VERSION 3.5) - -set(PUBLIC_HEADERS ${CMAKE_CURRENT_LIST_DIR}/qextserialport.h - ${CMAKE_CURRENT_LIST_DIR}/qextserialenumerator.h - ${CMAKE_CURRENT_LIST_DIR}/qextserialport_global.h - ) -list(APPEND EXTSERIAL_HEADERS - ${PUBLIC_HEADERS} - ${CMAKE_CURRENT_LIST_DIR}/qextserialport_p.h - ${CMAKE_CURRENT_LIST_DIR}/qextserialenumerator_p.h -) - - -list(APPEND EXTSERIAL_SOURCES - ${CMAKE_CURRENT_LIST_DIR}/qextserialport.cpp - ${CMAKE_CURRENT_LIST_DIR}/qextserialenumerator.cpp -) -IF (CMAKE_SYSTEM_NAME MATCHES "Linux") - message("CMAKE_SYSTEM_NAME is ${CMAKE_SYSTEM_NAME}") - list(APPEND NO_MOC_SOURCES ${CMAKE_CURRENT_LIST_DIR}/qextserialport_unix.cpp) - list(APPEND NO_MOC_SOURCES ${CMAKE_CURRENT_LIST_DIR}/qextserialenumerator_linux.cpp) - -ELSEIF (CMAKE_SYSTEM_NAME MATCHES "Windows") - message("CMAKE_SYSTEM_NAME is ${CMAKE_SYSTEM_NAME}") - list(APPEND NO_MOC_SOURCES ${CMAKE_CURRENT_LIST_DIR}/qextserialport_win.cpp) - list(APPEND NO_MOC_SOURCES ${CMAKE_CURRENT_LIST_DIR}/qextserialenumerator_win.cpp) - link_libraries(setupapi advapi32 user32) - -ELSEIF (CMAKE_SYSTEM_NAME MATCHES "FreeBSD") -message("CMAKE_SYSTEM_NAME is ${FreeBSD}") - -ENDIF() - -QT5_WRAP_CPP(EXTSERIAL_MOC ${EXTSERIAL_SOURCES} ) # moc预编译代码 -QT5_WRAP_CPP(EXTSERIAL_MOCHEADER ${EXTSERIAL_HEADERS} ) # moc预编译代码 - - -FOREACH(list ${EXTSERIAL_MOCHEADER}) - get_filename_component(BIN_PATH ${list} "DIRECTORY" ) - message("EXTSERIAL_MOCHEADER file" ${list} ${BIN_PATH}) - include_directories(${BIN_PATH}) -ENDFOREACH(list) - -# list(APPEND HEADERS ${EXTSERIAL_HEADERS}) -# list(APPEND SOURCES ${EXTSERIAL_SOURCES}) - -list(APPEND NO_MOC_SOURCES ${EXTSERIAL_SOURCES}) -include_directories(${CMAKE_CURRENT_LIST_DIR}) - - diff --git a/extserial/src/qextserialport.cpp b/extserial/src/qextserialport.cpp deleted file mode 100644 index d1089e2..0000000 --- a/extserial/src/qextserialport.cpp +++ /dev/null @@ -1,1005 +0,0 @@ -/**************************************************************************** -** Copyright (c) 2000-2003 Wayne Roth -** Copyright (c) 2004-2007 Stefan Sander -** Copyright (c) 2007 Michal Policht -** Copyright (c) 2008 Brandon Fosdick -** Copyright (c) 2009-2010 Liam Staskawicz -** Copyright (c) 2011 Debao Zhang -** All right reserved. -** Web: http://code.google.com/p/qextserialport/ -** -** Permission is hereby granted, free of charge, to any person obtaining -** a copy of this software and associated documentation files (the -** "Software"), to deal in the Software without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Software, and to -** permit persons to whom the Software is furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be -** included in all copies or substantial portions of the Software. -** -** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -** -****************************************************************************/ - -#include "qextserialport.h" -#include "qextserialport_p.h" -#include -#include -#include -#include - -/*! - \class PortSettings - - \brief The PortSettings class contain port settings - - Structure to contain port settings. - - \code - BaudRateType BaudRate; - DataBitsType DataBits; - ParityType Parity; - StopBitsType StopBits; - FlowType FlowControl; - long Timeout_Millisec; - \endcode -*/ - -QextSerialPortPrivate::QextSerialPortPrivate(QextSerialPort *q) - :lock(QReadWriteLock::Recursive), q_ptr(q) -{ - lastErr = E_NO_ERROR; - settings.BaudRate = BAUD9600; - settings.Parity = PAR_NONE; - settings.FlowControl = FLOW_OFF; - settings.DataBits = DATA_8; - settings.StopBits = STOP_1; - settings.Timeout_Millisec = 10; - settingsDirtyFlags = DFE_ALL; - - platformSpecificInit(); -} - -QextSerialPortPrivate::~QextSerialPortPrivate() -{ - platformSpecificDestruct(); -} - -void QextSerialPortPrivate::setBaudRate(BaudRateType baudRate, bool update) -{ - switch (baudRate) { -#ifdef Q_OS_WIN - //Windows Special - case BAUD14400: - case BAUD56000: - case BAUD128000: - case BAUD256000: - QESP_PORTABILITY_WARNING()<<"QextSerialPort Portability Warning: POSIX does not support baudRate:"<isOpen()) - updatePortSettings(); - break; -#if !(defined(Q_OS_WIN) || defined(Q_OS_MAC)) - default: - QESP_WARNING()<<"QextSerialPort does not support baudRate:"<isOpen()) - updatePortSettings(); -} - -void QextSerialPortPrivate::setDataBits(DataBitsType dataBits, bool update) -{ - switch(dataBits) { - - case DATA_5: - if (settings.StopBits == STOP_2) { - QESP_WARNING("QextSerialPort: 5 Data bits cannot be used with 2 stop bits."); - } else { - settings.DataBits = dataBits; - settingsDirtyFlags |= DFE_DataBits; - } - break; - - case DATA_6: -#ifdef Q_OS_WIN - if (settings.StopBits == STOP_1_5) { - QESP_WARNING("QextSerialPort: 6 Data bits cannot be used with 1.5 stop bits."); - } - else -#endif - { - settings.DataBits = dataBits; - settingsDirtyFlags |= DFE_DataBits; - } - break; - - case DATA_7: -#ifdef Q_OS_WIN - if (settings.StopBits == STOP_1_5) { - QESP_WARNING("QextSerialPort: 7 Data bits cannot be used with 1.5 stop bits."); - } - else -#endif - { - settings.DataBits = dataBits; - settingsDirtyFlags |= DFE_DataBits; - } - break; - - case DATA_8: -#ifdef Q_OS_WIN - if (settings.StopBits == STOP_1_5) { - QESP_WARNING("QextSerialPort: 8 Data bits cannot be used with 1.5 stop bits."); - } - else -#endif - { - settings.DataBits = dataBits; - settingsDirtyFlags |= DFE_DataBits; - } - break; - default: - QESP_WARNING()<<"QextSerialPort does not support Data bits:"<isOpen()) - updatePortSettings(); -} - -void QextSerialPortPrivate::setStopBits(StopBitsType stopBits, bool update) -{ - switch (stopBits) { - - /*one stop bit*/ - case STOP_1: - settings.StopBits = stopBits; - settingsDirtyFlags |= DFE_StopBits; - break; - -#ifdef Q_OS_WIN - /*1.5 stop bits*/ - case STOP_1_5: - QESP_PORTABILITY_WARNING("QextSerialPort Portability Warning: 1.5 stop bit operation is not supported by POSIX."); - if (settings.DataBits != DATA_5) { - QESP_WARNING("QextSerialPort: 1.5 stop bits can only be used with 5 data bits"); - } else { - settings.StopBits = stopBits; - settingsDirtyFlags |= DFE_StopBits; - } - break; -#endif - - /*two stop bits*/ - case STOP_2: - if (settings.DataBits == DATA_5) { - QESP_WARNING("QextSerialPort: 2 stop bits cannot be used with 5 data bits"); - } else { - settings.StopBits = stopBits; - settingsDirtyFlags |= DFE_StopBits; - } - break; - default: - QESP_WARNING()<<"QextSerialPort does not support stop bits: "<isOpen()) - updatePortSettings(); -} - -void QextSerialPortPrivate::setFlowControl(FlowType flow, bool update) -{ - settings.FlowControl = flow; - settingsDirtyFlags |= DFE_Flow; - if (update && q_func()->isOpen()) - updatePortSettings(); -} - -void QextSerialPortPrivate::setTimeout(long millisec, bool update) -{ - settings.Timeout_Millisec = millisec; - settingsDirtyFlags |= DFE_TimeOut; - if (update && q_func()->isOpen()) - updatePortSettings(); -} - -void QextSerialPortPrivate::setPortSettings(const PortSettings &settings, bool update) -{ - setBaudRate(settings.BaudRate, false); - setDataBits(settings.DataBits, false); - setStopBits(settings.StopBits, false); - setParity(settings.Parity, false); - setFlowControl(settings.FlowControl, false); - setTimeout(settings.Timeout_Millisec, false); - settingsDirtyFlags = DFE_ALL; - if (update && q_func()->isOpen()) - updatePortSettings(); -} - - -void QextSerialPortPrivate::_q_canRead() -{ - qint64 maxSize = bytesAvailable_sys(); - if (maxSize > 0) { - char *writePtr = readBuffer.reserve(size_t(maxSize)); - qint64 bytesRead = readData_sys(writePtr, maxSize); - if (bytesRead < maxSize) - readBuffer.chop(maxSize - bytesRead); - Q_Q(QextSerialPort); - Q_EMIT q->readyRead(); - } -} - -/*! \class QextSerialPort - - \brief The QextSerialPort class encapsulates a serial port on both POSIX and Windows systems. - - \section1 Usage - QextSerialPort offers both a polling and event driven API. Event driven - is typically easier to use, since you never have to worry about checking - for new data. - - \bold Example - \code - QextSerialPort *port = new QextSerialPort("COM1"); - connect(port, SIGNAL(readyRead()), myClass, SLOT(onDataAvailable())); - port->open(); - - void MyClass::onDataAvailable() - { - QByteArray data = port->readAll(); - processNewData(usbdata); - } - \endcode - - \section1 Compatibility - The user will be notified of errors and possible portability conflicts at run-time - by default. - - For example, if a application has used BAUD1800, when it is runing under unix, you - will get following message. - - \code - QextSerialPort Portability Warning: Windows does not support baudRate:1800 - \endcode - - This behavior can be turned off by defining macro QESP_NO_WARN (to turn off all warnings) - or QESP_NO_PORTABILITY_WARN (to turn off portability warnings) in the project. - - - \bold Author: Stefan Sander, Michal Policht, Brandon Fosdick, Liam Staskawicz, Debao Zhang -*/ - -/*! - \enum QextSerialPort::QueryMode - - This enum type specifies query mode used in a serial port: - - \value Polling - asynchronously read and write - \value EventDriven - synchronously read and write -*/ - -/*! - \fn void QextSerialPort::dsrChanged(bool status) - This signal is emitted whenever dsr line has changed its state. You may - use this signal to check if device is connected. - - \a status true when DSR signal is on, false otherwise. - */ - - -/*! - \fn QueryMode QextSerialPort::queryMode() const - Get query mode. - */ - -/*! - Default constructor. Note that the name of the device used by a QextSerialPort is dependent on - your OS. Possible naming conventions and their associated OS are: - - \code - - OS Constant Used By Naming Convention - ------------- ------------- ------------------------ - Q_OS_WIN Windows COM1, COM2 - Q_OS_IRIX SGI/IRIX /dev/ttyf1, /dev/ttyf2 - Q_OS_HPUX HP-UX /dev/tty1p0, /dev/tty2p0 - Q_OS_SOLARIS SunOS/Slaris /dev/ttya, /dev/ttyb - Q_OS_OSF Digital UNIX /dev/tty01, /dev/tty02 - Q_OS_FREEBSD FreeBSD /dev/ttyd0, /dev/ttyd1 - Q_OS_OPENBSD OpenBSD /dev/tty00, /dev/tty01 - Q_OS_LINUX Linux /dev/ttyS0, /dev/ttyS1 - /dev/ttyS0, /dev/ttyS1 - \endcode - - This constructor assigns the device name to the name of the first port on the specified system. - See the other constructors if you need to open a different port. Default \a mode is EventDriven. - As a subclass of QObject, \a parent can be specified. -*/ - -QextSerialPort::QextSerialPort(QextSerialPort::QueryMode mode, QObject *parent) - : QIODevice(parent), d_ptr(new QextSerialPortPrivate(this)) -{ -#ifdef Q_OS_WIN - setPortName(QLatin1String("COM1")); - -#elif defined(Q_OS_IRIX) - setPortName(QLatin1String("/dev/ttyf1")); - -#elif defined(Q_OS_HPUX) - setPortName(QLatin1String("/dev/tty1p0")); - -#elif defined(Q_OS_SOLARIS) - setPortName(QLatin1String("/dev/ttya")); - -#elif defined(Q_OS_OSF) //formally DIGITAL UNIX - setPortName(QLatin1String("/dev/tty01")); - -#elif defined(Q_OS_FREEBSD) - setPortName(QLatin1String("/dev/ttyd1")); - -#elif defined(Q_OS_OPENBSD) - setPortName(QLatin1String("/dev/tty00")); - -#else - setPortName(QLatin1String("/dev/ttyS0")); -#endif - setQueryMode(mode); -} - -/*! - Constructs a serial port attached to the port specified by name. - \a name is the name of the device, which is windowsystem-specific, - e.g."COM1" or "/dev/ttyS0". \a mode -*/ -QextSerialPort::QextSerialPort(const QString &name, QextSerialPort::QueryMode mode, QObject *parent) - : QIODevice(parent), d_ptr(new QextSerialPortPrivate(this)) -{ - setQueryMode(mode); - setPortName(name); -} - -/*! - Constructs a port with default name and specified \a settings. -*/ -QextSerialPort::QextSerialPort(const PortSettings &settings, QextSerialPort::QueryMode mode, QObject *parent) - : QIODevice(parent), d_ptr(new QextSerialPortPrivate(this)) -{ - Q_D(QextSerialPort); - setQueryMode(mode); - d->setPortSettings(settings); -} - -/*! - Constructs a port with specified \a name , \a mode and \a settings. -*/ -QextSerialPort::QextSerialPort(const QString &name, const PortSettings &settings, QextSerialPort::QueryMode mode, QObject *parent) - : QIODevice(parent), d_ptr(new QextSerialPortPrivate(this)) -{ - Q_D(QextSerialPort); - setPortName(name); - setQueryMode(mode); - d->setPortSettings(settings); -} - -/*! - Opens a serial port and sets its OpenMode to \a mode. - Note that this function does not specify which device to open. - Returns true if successful; otherwise returns false.This function has no effect - if the port associated with the class is already open. The port is also - configured to the current settings, as stored in the settings structure. -*/ -bool QextSerialPort::open(OpenMode mode) -{ - Q_D(QextSerialPort); - QWriteLocker locker(&d->lock); - if (mode != QIODevice::NotOpen && !isOpen()) - d->open_sys(mode); - - return isOpen(); -} - - -/*! \reimp - Closes a serial port. This function has no effect if the serial port associated with the class - is not currently open. -*/ -void QextSerialPort::close() -{ - Q_D(QextSerialPort); - QWriteLocker locker(&d->lock); - if (isOpen()) { - // Be a good QIODevice and call QIODevice::close() before really close() - // so the aboutToClose() signal is emitted at the proper time - QIODevice::close(); // mark ourselves as closed - d->close_sys(); - d->readBuffer.clear(); - } -} - -/*! - Flushes all pending I/O to the serial port. This function has no effect if the serial port - associated with the class is not currently open. -*/ -void QextSerialPort::flush() -{ - Q_D(QextSerialPort); - QWriteLocker locker(&d->lock); - if (isOpen()) - d->flush_sys(); -} - -/*! \reimp - Returns the number of bytes waiting in the port's receive queue. This function will return 0 if - the port is not currently open, or -1 on error. -*/ -qint64 QextSerialPort::bytesAvailable() const -{ - QWriteLocker locker(&d_func()->lock); - if (isOpen()) { - qint64 bytes = d_func()->bytesAvailable_sys(); - if (bytes != -1) { - return bytes + d_func()->readBuffer.size() - + QIODevice::bytesAvailable(); - } - return -1; - } - return 0; -} - -/*! \reimp - -*/ -bool QextSerialPort::canReadLine() const -{ - QReadLocker locker(&d_func()->lock); - return QIODevice::canReadLine() || d_func()->readBuffer.canReadLine(); -} - -/*! - * Set desired serial communication handling style. You may choose from polling - * or event driven approach. This function does nothing when port is open; to - * apply changes port must be reopened. - * - * In event driven approach read() and write() functions are acting - * asynchronously. They return immediately and the operation is performed in - * the background, so they doesn't freeze the calling thread. - * To determine when operation is finished, QextSerialPort runs separate thread - * and monitors serial port events. Whenever the event occurs, adequate signal - * is emitted. - * - * When polling is set, read() and write() are acting synchronously. Signals are - * not working in this mode and some functions may not be available. The advantage - * of polling is that it generates less overhead due to lack of signals emissions - * and it doesn't start separate thread to monitor events. - * - * Generally event driven approach is more capable and friendly, although some - * applications may need as low overhead as possible and then polling comes. - * - * \a mode query mode. - */ -void QextSerialPort::setQueryMode(QueryMode mode) -{ - Q_D(QextSerialPort); - QWriteLocker locker(&d->lock); - if (mode != d->queryMode) - d->queryMode = mode; -} - -/*! - Sets the \a name of the device associated with the object, e.g. "COM1", or "/dev/ttyS0". -*/ -void QextSerialPort::setPortName(const QString &name) -{ - Q_D(QextSerialPort); - QWriteLocker locker(&d->lock); - d->port = name; -} - -/*! - Returns the name set by setPortName(). -*/ -QString QextSerialPort::portName() const -{ - QReadLocker locker(&d_func()->lock); - return d_func()->port; -} - -QextSerialPort::QueryMode QextSerialPort::queryMode() const -{ - QReadLocker locker(&d_func()->lock); - return d_func()->queryMode; -} - -/*! - Reads all available data from the device, and returns it as a QByteArray. - This function has no way of reporting errors; returning an empty QByteArray() - can mean either that no data was currently available for reading, or that an error occurred. -*/ -QByteArray QextSerialPort::readAll() -{ - int avail = this->bytesAvailable(); - return (avail > 0) ? this->read(avail) : QByteArray(); -} - -/*! - Returns the baud rate of the serial port. For a list of possible return values see - the definition of the enum BaudRateType. -*/ -BaudRateType QextSerialPort::baudRate() const -{ - QReadLocker locker(&d_func()->lock); - return d_func()->settings.BaudRate; -} - -/*! - Returns the number of data bits used by the port. For a list of possible values returned by - this function, see the definition of the enum DataBitsType. -*/ -DataBitsType QextSerialPort::dataBits() const -{ - QReadLocker locker(&d_func()->lock); - return d_func()->settings.DataBits; -} - -/*! - Returns the type of parity used by the port. For a list of possible values returned by - this function, see the definition of the enum ParityType. -*/ -ParityType QextSerialPort::parity() const -{ - QReadLocker locker(&d_func()->lock); - return d_func()->settings.Parity; -} - -/*! - Returns the number of stop bits used by the port. For a list of possible return values, see - the definition of the enum StopBitsType. -*/ -StopBitsType QextSerialPort::stopBits() const -{ - QReadLocker locker(&d_func()->lock); - return d_func()->settings.StopBits; -} - -/*! - Returns the type of flow control used by the port. For a list of possible values returned - by this function, see the definition of the enum FlowType. -*/ -FlowType QextSerialPort::flowControl() const -{ - QReadLocker locker(&d_func()->lock); - return d_func()->settings.FlowControl; -} - -/*! - \reimp - Returns true if device is sequential, otherwise returns false. Serial port is sequential device - so this function always returns true. Check QIODevice::isSequential() documentation for more - information. -*/ -bool QextSerialPort::isSequential() const -{ - return true; -} - -/*! - Return the error number, or 0 if no error occurred. -*/ -ulong QextSerialPort::lastError() const -{ - QReadLocker locker(&d_func()->lock); - return d_func()->lastErr; -} - -/*! - Returns the line status as stored by the port function. This function will retrieve the states - of the following lines: DCD, CTS, DSR, and RI. On POSIX systems, the following additional lines - can be monitored: DTR, RTS, Secondary TXD, and Secondary RXD. The value returned is an unsigned - long with specific bits indicating which lines are high. The following constants should be used - to examine the states of individual lines: - - \code - Mask Line - ------ ---- - LS_CTS CTS - LS_DSR DSR - LS_DCD DCD - LS_RI RI - LS_RTS RTS (POSIX only) - LS_DTR DTR (POSIX only) - LS_ST Secondary TXD (POSIX only) - LS_SR Secondary RXD (POSIX only) - \endcode - - This function will return 0 if the port associated with the class is not currently open. -*/ -unsigned long QextSerialPort::lineStatus() -{ - Q_D(QextSerialPort); - QWriteLocker locker(&d->lock); - if (isOpen()) - return d->lineStatus_sys(); - return 0; -} - -/*! - Returns a human-readable description of the last device error that occurred. -*/ -QString QextSerialPort::errorString() -{ - Q_D(QextSerialPort); - QReadLocker locker(&d->lock); - switch(d->lastErr) { - case E_NO_ERROR: - return tr("No Error has occurred"); - case E_INVALID_FD: - return tr("Invalid file descriptor (port was not opened correctly)"); - case E_NO_MEMORY: - return tr("Unable to allocate memory tables (POSIX)"); - case E_CAUGHT_NON_BLOCKED_SIGNAL: - return tr("Caught a non-blocked signal (POSIX)"); - case E_PORT_TIMEOUT: - return tr("Operation timed out (POSIX)"); - case E_INVALID_DEVICE: - return tr("The file opened by the port is not a valid device"); - case E_BREAK_CONDITION: - return tr("The port detected a break condition"); - case E_FRAMING_ERROR: - return tr("The port detected a framing error (usually caused by incorrect baud rate settings)"); - case E_IO_ERROR: - return tr("There was an I/O error while communicating with the port"); - case E_BUFFER_OVERRUN: - return tr("Character buffer overrun"); - case E_RECEIVE_OVERFLOW: - return tr("Receive buffer overflow"); - case E_RECEIVE_PARITY_ERROR: - return tr("The port detected a parity error in the received data"); - case E_TRANSMIT_OVERFLOW: - return tr("Transmit buffer overflow"); - case E_READ_FAILED: - return tr("General read operation failure"); - case E_WRITE_FAILED: - return tr("General write operation failure"); - case E_FILE_NOT_FOUND: - return tr("The %1 file doesn't exists").arg(this->portName()); - case E_PERMISSION_DENIED: - return tr("Permission denied"); - case E_AGAIN: - return tr("Device is already locked"); - default: - return tr("Unknown error: %1").arg(d->lastErr); - } -} - -/*! - Destructs the QextSerialPort object. -*/ -QextSerialPort::~QextSerialPort() -{ - if (isOpen()) - close(); - - delete d_ptr; -} - -/*! - Sets the flow control used by the port to \a flow. Possible values of flow are: - \code - FLOW_OFF No flow control - FLOW_HARDWARE Hardware (RTS/CTS) flow control - FLOW_XONXOFF Software (XON/XOFF) flow control - \endcode -*/ -void QextSerialPort::setFlowControl(FlowType flow) -{ - Q_D(QextSerialPort); - QWriteLocker locker(&d->lock); - if (d->settings.FlowControl != flow) - d->setFlowControl(flow, true); -} - -/*! - Sets the parity associated with the serial port to \a parity. The possible values of parity are: - \code - PAR_SPACE Space Parity - PAR_MARK Mark Parity - PAR_NONE No Parity - PAR_EVEN Even Parity - PAR_ODD Odd Parity - \endcode -*/ -void QextSerialPort::setParity(ParityType parity) -{ - Q_D(QextSerialPort); - QWriteLocker locker(&d->lock); - if (d->settings.Parity != parity) - d->setParity(parity, true); -} - -/*! - Sets the number of data bits used by the serial port to \a dataBits. Possible values of dataBits are: - \code - DATA_5 5 data bits - DATA_6 6 data bits - DATA_7 7 data bits - DATA_8 8 data bits - \endcode - - \bold note: - This function is subject to the following restrictions: - \list - \o 5 data bits cannot be used with 2 stop bits. - \o 1.5 stop bits can only be used with 5 data bits. - \o 8 data bits cannot be used with space parity on POSIX systems. - \endlist - */ -void QextSerialPort::setDataBits(DataBitsType dataBits) -{ - Q_D(QextSerialPort); - QWriteLocker locker(&d->lock); - if (d->settings.DataBits != dataBits) - d->setDataBits(dataBits, true); -} - -/*! - Sets the number of stop bits used by the serial port to \a stopBits. Possible values of stopBits are: - \code - STOP_1 1 stop bit - STOP_1_5 1.5 stop bits - STOP_2 2 stop bits - \endcode - - \bold note: - This function is subject to the following restrictions: - \list - \o 2 stop bits cannot be used with 5 data bits. - \o 1.5 stop bits cannot be used with 6 or more data bits. - \o POSIX does not support 1.5 stop bits. - \endlist -*/ -void QextSerialPort::setStopBits(StopBitsType stopBits) -{ - Q_D(QextSerialPort); - QWriteLocker locker(&d->lock); - if (d->settings.StopBits != stopBits) - d->setStopBits(stopBits, true); -} - -/*! - Sets the baud rate of the serial port to \a baudRate. Note that not all rates are applicable on - all platforms. The following table shows translations of the various baud rate - constants on Windows(including NT/2000) and POSIX platforms. Speeds marked with an * - are speeds that are usable on both Windows and POSIX. - \code - - RATE Windows Speed POSIX Speed - ----------- ------------- ----------- - BAUD50 X 50 - BAUD75 X 75 - *BAUD110 110 110 - BAUD134 X 134.5 - BAUD150 X 150 - BAUD200 X 200 - *BAUD300 300 300 - *BAUD600 600 600 - *BAUD1200 1200 1200 - BAUD1800 X 1800 - *BAUD2400 2400 2400 - *BAUD4800 4800 4800 - *BAUD9600 9600 9600 - BAUD14400 14400 X - *BAUD19200 19200 19200 - *BAUD38400 38400 38400 - BAUD56000 56000 X - *BAUD57600 57600 57600 - BAUD76800 X 76800 - *BAUD115200 115200 115200 - BAUD128000 128000 X - BAUD230400 X 230400 - BAUD256000 256000 X - BAUD460800 X 460800 - BAUD500000 X 500000 - BAUD576000 X 576000 - BAUD921600 X 921600 - BAUD1000000 X 1000000 - BAUD1152000 X 1152000 - BAUD1500000 X 1500000 - BAUD2000000 X 2000000 - BAUD2500000 X 2500000 - BAUD3000000 X 3000000 - BAUD3500000 X 3500000 - BAUD4000000 X 4000000 - \endcode -*/ - -void QextSerialPort::setBaudRate(BaudRateType baudRate) -{ - Q_D(QextSerialPort); - QWriteLocker locker(&d->lock); - if (d->settings.BaudRate != baudRate) - d->setBaudRate(baudRate, true); -} - -/*! - For Unix: - - Sets the read and write timeouts for the port to \a millisec milliseconds. - Note that this is a per-character timeout, i.e. the port will wait this long for each - individual character, not for the whole read operation. This timeout also applies to the - bytesWaiting() function. - - \bold note: - POSIX does not support millisecond-level control for I/O timeout values. Any - timeout set using this function will be set to the next lowest tenth of a second for - the purposes of detecting read or write timeouts. For example a timeout of 550 milliseconds - will be seen by the class as a timeout of 500 milliseconds for the purposes of reading and - writing the port. However millisecond-level control is allowed by the select() system call, - so for example a 550-millisecond timeout will be seen as 550 milliseconds on POSIX systems for - the purpose of detecting available bytes in the read buffer. - - For Windows: - - Sets the read and write timeouts for the port to \a millisec milliseconds. - Setting 0 indicates that timeouts are not used for read nor write operations; - however read() and write() functions will still block. Set -1 to provide - non-blocking behaviour (read() and write() will return immediately). - - \bold note: this function does nothing in event driven mode. -*/ -void QextSerialPort::setTimeout(long millisec) -{ - Q_D(QextSerialPort); - QWriteLocker locker(&d->lock); - if (d->settings.Timeout_Millisec != millisec) - d->setTimeout(millisec, true); -} - -/*! - Sets DTR line to the requested state (\a set default to high). This function will have no effect if - the port associated with the class is not currently open. -*/ -void QextSerialPort::setDtr(bool set) -{ - Q_D(QextSerialPort); - QWriteLocker locker(&d->lock); - if (isOpen()) - d->setDtr_sys(set); -} - -/*! - Sets RTS line to the requested state \a set (high by default). - This function will have no effect if - the port associated with the class is not currently open. -*/ -void QextSerialPort::setRts(bool set) -{ - Q_D(QextSerialPort); - QWriteLocker locker(&d->lock); - if (isOpen()) - d->setRts_sys(set); -} - -/*! \reimp - Reads a block of data from the serial port. This function will read at most maxlen bytes from - the serial port and place them in the buffer pointed to by data. Return value is the number of - bytes actually read, or -1 on error. - - \warning before calling this function ensure that serial port associated with this class - is currently open (use isOpen() function to check if port is open). -*/ -qint64 QextSerialPort::readData(char *data, qint64 maxSize) -{ - Q_D(QextSerialPort); - QWriteLocker locker(&d->lock); - qint64 bytesFromBuffer = 0; - if (!d->readBuffer.isEmpty()) { - bytesFromBuffer = d->readBuffer.read(data, maxSize); - if (bytesFromBuffer == maxSize) - return bytesFromBuffer; - } - qint64 bytesFromDevice = d->readData_sys(data+bytesFromBuffer, maxSize-bytesFromBuffer); - if (bytesFromDevice < 0) - return -1; - return bytesFromBuffer + bytesFromDevice; -} - -/*! \reimp - Writes a block of data to the serial port. This function will write len bytes - from the buffer pointed to by data to the serial port. Return value is the number - of bytes actually written, or -1 on error. - - \warning before calling this function ensure that serial port associated with this class - is currently open (use isOpen() function to check if port is open). -*/ -qint64 QextSerialPort::writeData(const char *data, qint64 maxSize) -{ - Q_D(QextSerialPort); - QWriteLocker locker(&d->lock); - return d->writeData_sys(data, maxSize); -} - -#include "moc_qextserialport.cpp" diff --git a/extserial/src/qextserialport.h b/extserial/src/qextserialport.h deleted file mode 100644 index a0bc822..0000000 --- a/extserial/src/qextserialport.h +++ /dev/null @@ -1,240 +0,0 @@ -/**************************************************************************** -** Copyright (c) 2000-2003 Wayne Roth -** Copyright (c) 2004-2007 Stefan Sander -** Copyright (c) 2007 Michal Policht -** Copyright (c) 2008 Brandon Fosdick -** Copyright (c) 2009-2010 Liam Staskawicz -** Copyright (c) 2011 Debao Zhang -** All right reserved. -** Web: http://code.google.com/p/qextserialport/ -** -** Permission is hereby granted, free of charge, to any person obtaining -** a copy of this software and associated documentation files (the -** "Software"), to deal in the Software without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Software, and to -** permit persons to whom the Software is furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be -** included in all copies or substantial portions of the Software. -** -** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -** -****************************************************************************/ - -#ifndef _QEXTSERIALPORT_H_ -#define _QEXTSERIALPORT_H_ - -#include -#include "qextserialport_global.h" -#ifdef Q_OS_UNIX -#include -#endif -/*line status constants*/ -// ### QESP2.0 move to enum -#define LS_CTS 0x01 -#define LS_DSR 0x02 -#define LS_DCD 0x04 -#define LS_RI 0x08 -#define LS_RTS 0x10 -#define LS_DTR 0x20 -#define LS_ST 0x40 -#define LS_SR 0x80 - -/*error constants*/ -// ### QESP2.0 move to enum -#define E_NO_ERROR 0 -#define E_INVALID_FD 1 -#define E_NO_MEMORY 2 -#define E_CAUGHT_NON_BLOCKED_SIGNAL 3 -#define E_PORT_TIMEOUT 4 -#define E_INVALID_DEVICE 5 -#define E_BREAK_CONDITION 6 -#define E_FRAMING_ERROR 7 -#define E_IO_ERROR 8 -#define E_BUFFER_OVERRUN 9 -#define E_RECEIVE_OVERFLOW 10 -#define E_RECEIVE_PARITY_ERROR 11 -#define E_TRANSMIT_OVERFLOW 12 -#define E_READ_FAILED 13 -#define E_WRITE_FAILED 14 -#define E_FILE_NOT_FOUND 15 -#define E_PERMISSION_DENIED 16 -#define E_AGAIN 17 - -enum BaudRateType -{ -#if defined(Q_OS_UNIX) || defined(qdoc) - BAUD50 = 50, //POSIX ONLY - BAUD75 = 75, //POSIX ONLY - BAUD134 = 134, //POSIX ONLY - BAUD150 = 150, //POSIX ONLY - BAUD200 = 200, //POSIX ONLY - BAUD1800 = 1800, //POSIX ONLY -# if defined(B76800) || defined(qdoc) - BAUD76800 = 76800, //POSIX ONLY -# endif -# if (defined(B230400) && defined(B4000000)) || defined(qdoc) - BAUD230400 = 230400, //POSIX ONLY - BAUD460800 = 460800, //POSIX ONLY - BAUD500000 = 500000, //POSIX ONLY - BAUD576000 = 576000, //POSIX ONLY - BAUD921600 = 921600, //POSIX ONLY - BAUD1000000 = 1000000, //POSIX ONLY - BAUD1152000 = 1152000, //POSIX ONLY - BAUD1500000 = 1500000, //POSIX ONLY - BAUD2000000 = 2000000, //POSIX ONLY - BAUD2500000 = 2500000, //POSIX ONLY - BAUD3000000 = 3000000, //POSIX ONLY - BAUD3500000 = 3500000, //POSIX ONLY - BAUD4000000 = 4000000, //POSIX ONLY -# endif -#endif //Q_OS_UNIX -#if defined(Q_OS_WIN) || defined(qdoc) - BAUD14400 = 14400, //WINDOWS ONLY - BAUD56000 = 56000, //WINDOWS ONLY - BAUD128000 = 128000, //WINDOWS ONLY - BAUD256000 = 256000, //WINDOWS ONLY -#endif //Q_OS_WIN - BAUD110 = 110, - BAUD300 = 300, - BAUD600 = 600, - BAUD1200 = 1200, - BAUD2400 = 2400, - BAUD4800 = 4800, - BAUD9600 = 9600, - BAUD19200 = 19200, - BAUD38400 = 38400, - BAUD57600 = 57600, - BAUD115200 = 115200 -}; - -enum DataBitsType -{ - DATA_5 = 5, - DATA_6 = 6, - DATA_7 = 7, - DATA_8 = 8 -}; - -enum ParityType -{ - PAR_NONE, - PAR_ODD, - PAR_EVEN, -#if defined(Q_OS_WIN) || defined(qdoc) - PAR_MARK, //WINDOWS ONLY -#endif - PAR_SPACE -}; - -enum StopBitsType -{ - STOP_1, -#if defined(Q_OS_WIN) || defined(qdoc) - STOP_1_5, //WINDOWS ONLY -#endif - STOP_2 -}; - -enum FlowType -{ - FLOW_OFF, - FLOW_HARDWARE, - FLOW_XONXOFF -}; - -/** - * structure to contain port settings - */ -struct PortSettings -{ - BaudRateType BaudRate; - DataBitsType DataBits; - ParityType Parity; - StopBitsType StopBits; - FlowType FlowControl; - long Timeout_Millisec; -}; - -class QextSerialPortPrivate; -class QEXTSERIALPORT_EXPORT QextSerialPort: public QIODevice -{ - Q_OBJECT - Q_DECLARE_PRIVATE(QextSerialPort) - Q_ENUMS(QueryMode) - Q_PROPERTY(QString portName READ portName WRITE setPortName) - Q_PROPERTY(QueryMode queryMode READ queryMode WRITE setQueryMode) -public: - enum QueryMode { - Polling, - EventDriven - }; - - explicit QextSerialPort(QueryMode mode = EventDriven, QObject *parent = 0); - explicit QextSerialPort(const QString &name, QueryMode mode = EventDriven, QObject *parent = 0); - explicit QextSerialPort(const PortSettings &s, QueryMode mode = EventDriven, QObject *parent = 0); - QextSerialPort(const QString &name, const PortSettings &s, QueryMode mode = EventDriven, QObject *parent=0); - - ~QextSerialPort(); - - QString portName() const; - QueryMode queryMode() const; - BaudRateType baudRate() const; - DataBitsType dataBits() const; - ParityType parity() const; - StopBitsType stopBits() const; - FlowType flowControl() const; - - bool open(OpenMode mode); - bool isSequential() const; - void close(); - void flush(); - qint64 bytesAvailable() const; - bool canReadLine() const; - QByteArray readAll(); - - ulong lastError() const; - - ulong lineStatus(); - QString errorString(); - -public Q_SLOTS: - void setPortName(const QString &name); - void setQueryMode(QueryMode mode); - void setBaudRate(BaudRateType); - void setDataBits(DataBitsType); - void setParity(ParityType); - void setStopBits(StopBitsType); - void setFlowControl(FlowType); - void setTimeout(long); - - void setDtr(bool set=true); - void setRts(bool set=true); - -Q_SIGNALS: - void dsrChanged(bool status); - -protected: - qint64 readData(char *data, qint64 maxSize); - qint64 writeData(const char *data, qint64 maxSize); - -private: - Q_DISABLE_COPY(QextSerialPort) - -#ifdef Q_OS_WIN - Q_PRIVATE_SLOT(d_func(), void _q_onWinEvent(HANDLE)) -#endif - Q_PRIVATE_SLOT(d_func(), void _q_canRead()) - - QextSerialPortPrivate * const d_ptr; -}; - -#endif diff --git a/extserial/src/qextserialport.pri b/extserial/src/qextserialport.pri deleted file mode 100644 index 27b05ef..0000000 --- a/extserial/src/qextserialport.pri +++ /dev/null @@ -1,36 +0,0 @@ -INCLUDEPATH += $$PWD -DEPENDPATH += $$PWD - -PUBLIC_HEADERS += $$PWD/qextserialport.h \ - $$PWD/qextserialenumerator.h \ - $$PWD/qextserialport_global.h - -HEADERS += $$PUBLIC_HEADERS \ - $$PWD/qextserialport_p.h \ - $$PWD/qextserialenumerator_p.h \ - -SOURCES += $$PWD/qextserialport.cpp \ - $$PWD/qextserialenumerator.cpp -unix { - SOURCES += $$PWD/qextserialport_unix.cpp - linux* { - SOURCES += $$PWD/qextserialenumerator_linux.cpp - } else:macx { - SOURCES += $$PWD/qextserialenumerator_osx.cpp - } else { - SOURCES += $$PWD/qextserialenumerator_unix.cpp - } -} -win32:SOURCES += $$PWD/qextserialport_win.cpp \ - $$PWD/qextserialenumerator_win.cpp - -linux*{ - !qesp_linux_udev:DEFINES += QESP_NO_UDEV - qesp_linux_udev: LIBS += -ludev -} - -macx:LIBS += -framework IOKit -framework CoreFoundation -win32:LIBS += -lsetupapi -ladvapi32 -luser32 - -# moc doesn't detect Q_OS_LINUX correctly, so add this to make it work -linux*:DEFINES += __linux__ diff --git a/extserial/src/qextserialport_global.h b/extserial/src/qextserialport_global.h deleted file mode 100644 index 507d2cf..0000000 --- a/extserial/src/qextserialport_global.h +++ /dev/null @@ -1,72 +0,0 @@ -/**************************************************************************** -** Copyright (c) 2000-2003 Wayne Roth -** Copyright (c) 2004-2007 Stefan Sander -** Copyright (c) 2007 Michal Policht -** Copyright (c) 2008 Brandon Fosdick -** Copyright (c) 2009-2010 Liam Staskawicz -** Copyright (c) 2011 Debao Zhang -** All right reserved. -** Web: http://code.google.com/p/qextserialport/ -** -** Permission is hereby granted, free of charge, to any person obtaining -** a copy of this software and associated documentation files (the -** "Software"), to deal in the Software without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Software, and to -** permit persons to whom the Software is furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be -** included in all copies or substantial portions of the Software. -** -** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -** -****************************************************************************/ - -#ifndef QEXTSERIALPORT_GLOBAL_H -#define QEXTSERIALPORT_GLOBAL_H - -#include - -#ifdef QEXTSERIALPORT_BUILD_SHARED -# define QEXTSERIALPORT_EXPORT Q_DECL_EXPORT -#elif defined(QEXTSERIALPORT_USING_SHARED) -# define QEXTSERIALPORT_EXPORT Q_DECL_IMPORT -#else -# define QEXTSERIALPORT_EXPORT -#endif - -// ### for compatible with old version. should be removed in QESP 2.0 -#ifdef _TTY_NOWARN_ -# define QESP_NO_WARN -#endif -#ifdef _TTY_NOWARN_PORT_ -# define QESP_NO_PORTABILITY_WARN -#endif - -/*if all warning messages are turned off, flag portability warnings to be turned off as well*/ -#ifdef QESP_NO_WARN -# define QESP_NO_PORTABILITY_WARN -#endif - -/*macros for warning and debug messages*/ -#ifdef QESP_NO_PORTABILITY_WARN -# define QESP_PORTABILITY_WARNING while (false)qWarning -#else -# define QESP_PORTABILITY_WARNING qWarning -#endif /*QESP_NOWARN_PORT*/ - -#ifdef QESP_NO_WARN -# define QESP_WARNING while (false)qWarning -#else -# define QESP_WARNING qWarning -#endif /*QESP_NOWARN*/ - -#endif // QEXTSERIALPORT_GLOBAL_H - diff --git a/extserial/src/qextserialport_p.h b/extserial/src/qextserialport_p.h deleted file mode 100644 index 31cea71..0000000 --- a/extserial/src/qextserialport_p.h +++ /dev/null @@ -1,250 +0,0 @@ -/**************************************************************************** -** Copyright (c) 2000-2003 Wayne Roth -** Copyright (c) 2004-2007 Stefan Sander -** Copyright (c) 2007 Michal Policht -** Copyright (c) 2008 Brandon Fosdick -** Copyright (c) 2009-2010 Liam Staskawicz -** Copyright (c) 2011 Debao Zhang -** All right reserved. -** Web: http://code.google.com/p/qextserialport/ -** -** Permission is hereby granted, free of charge, to any person obtaining -** a copy of this software and associated documentation files (the -** "Software"), to deal in the Software without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Software, and to -** permit persons to whom the Software is furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be -** included in all copies or substantial portions of the Software. -** -** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -** -****************************************************************************/ - -#ifndef _QEXTSERIALPORT_P_H_ -#define _QEXTSERIALPORT_P_H_ - -// -// W A R N I N G -// ------------- -// -// This file is not part of the QESP API. It exists for the convenience -// of other QESP classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qextserialport.h" -#include -#ifdef Q_OS_UNIX -# include -#elif (defined Q_OS_WIN) -# include -#endif -#include - -// This is QextSerialPort's read buffer, needed by posix system. -// ref: QRingBuffer & QIODevicePrivateLinearBuffer -class QextReadBuffer -{ -public: - inline QextReadBuffer(size_t growth=4096) - : len(0), first(0), buf(0), capacity(0), basicBlockSize(growth) { - } - - ~QextReadBuffer() { - delete [] buf; - } - - inline void clear() { - first = buf; - len = 0; - } - - inline int size() const { - return len; - } - - inline bool isEmpty() const { - return len == 0; - } - - inline int read(char *target, int size) { - int r = qMin(size, len); - if (r == 1) { - *target = *first; - --len; - ++first; - } else { - memcpy(target, first, r); - len -= r; - first += r; - } - return r; - } - - inline char *reserve(size_t size) { - if ((first - buf) + len + size > capacity) { - size_t newCapacity = qMax(capacity, basicBlockSize); - while (newCapacity < len + size) - newCapacity *= 2; - if (newCapacity > capacity) { - // allocate more space - char *newBuf = new char[newCapacity]; - memmove(newBuf, first, len); - delete [] buf; - buf = newBuf; - capacity = newCapacity; - } else { - // shift any existing data to make space - memmove(buf, first, len); - } - first = buf; - } - char *writePtr = first + len; - len += (int)size; - return writePtr; - } - - inline void chop(int size) { - if (size >= len) - clear(); - else - len -= size; - } - - inline void squeeze() { - if (first != buf) { - memmove(buf, first, len); - first = buf; - } - size_t newCapacity = basicBlockSize; - while (newCapacity < size_t(len)) - newCapacity *= 2; - if (newCapacity < capacity) { - char *tmp = static_cast(realloc(buf, newCapacity)); - if (tmp) { - buf = tmp; - capacity = newCapacity; - } - } - } - - inline QByteArray readAll() { - char *f = first; - int l = len; - clear(); - return QByteArray(f, l); - } - - inline int readLine(char *target, int size) { - int r = qMin(size, len); - char *eol = static_cast(memchr(first, '\n', r)); - if (eol) - r = 1+(eol-first); - memcpy(target, first, r); - len -= r; - first += r; - return int(r); - } - - inline bool canReadLine() const { - return memchr(first, '\n', len); - } - -private: - int len; - char *first; - char *buf; - size_t capacity; - size_t basicBlockSize; -}; - -class QWinEventNotifier; -class QReadWriteLock; -class QSocketNotifier; - -class QextSerialPortPrivate -{ - Q_DECLARE_PUBLIC(QextSerialPort) -public: - QextSerialPortPrivate(QextSerialPort *q); - ~QextSerialPortPrivate(); - enum DirtyFlagEnum - { - DFE_BaudRate = 0x0001, - DFE_Parity = 0x0002, - DFE_StopBits = 0x0004, - DFE_DataBits = 0x0008, - DFE_Flow = 0x0010, - DFE_TimeOut = 0x0100, - DFE_ALL = 0x0fff, - DFE_Settings_Mask = 0x00ff //without TimeOut - }; - mutable QReadWriteLock lock; - QString port; - PortSettings settings; - QextReadBuffer readBuffer; - int settingsDirtyFlags; - ulong lastErr; - QextSerialPort::QueryMode queryMode; - - // platform specific members -#ifdef Q_OS_UNIX - int fd; - QSocketNotifier *readNotifier; - struct termios currentTermios; - struct termios oldTermios; -#elif (defined Q_OS_WIN) - HANDLE handle; - OVERLAPPED overlap; - COMMCONFIG commConfig; - COMMTIMEOUTS commTimeouts; - QWinEventNotifier *winEventNotifier; - DWORD eventMask; - QList pendingWrites; - QReadWriteLock *bytesToWriteLock; -#endif - - /*fill PortSettings*/ - void setBaudRate(BaudRateType baudRate, bool update=true); - void setDataBits(DataBitsType dataBits, bool update=true); - void setParity(ParityType parity, bool update=true); - void setStopBits(StopBitsType stopbits, bool update=true); - void setFlowControl(FlowType flow, bool update=true); - void setTimeout(long millisec, bool update=true); - void setPortSettings(const PortSettings &settings, bool update=true); - - void platformSpecificDestruct(); - void platformSpecificInit(); - void translateError(ulong error); - void updatePortSettings(); - - qint64 readData_sys(char *data, qint64 maxSize); - qint64 writeData_sys(const char *data, qint64 maxSize); - void setDtr_sys(bool set=true); - void setRts_sys(bool set=true); - bool open_sys(QIODevice::OpenMode mode); - bool close_sys(); - bool flush_sys(); - ulong lineStatus_sys(); - qint64 bytesAvailable_sys() const; - -#ifdef Q_OS_WIN - void _q_onWinEvent(HANDLE h); -#endif - void _q_canRead(); - - QextSerialPort *q_ptr; -}; - -#endif //_QEXTSERIALPORT_P_H_ diff --git a/extserial/src/qextserialport_unix.cpp b/extserial/src/qextserialport_unix.cpp deleted file mode 100644 index 09c6568..0000000 --- a/extserial/src/qextserialport_unix.cpp +++ /dev/null @@ -1,458 +0,0 @@ -/**************************************************************************** -** Copyright (c) 2000-2003 Wayne Roth -** Copyright (c) 2004-2007 Stefan Sander -** Copyright (c) 2007 Michal Policht -** Copyright (c) 2008 Brandon Fosdick -** Copyright (c) 2009-2010 Liam Staskawicz -** Copyright (c) 2011 Debao Zhang -** All right reserved. -** Web: http://code.google.com/p/qextserialport/ -** -** Permission is hereby granted, free of charge, to any person obtaining -** a copy of this software and associated documentation files (the -** "Software"), to deal in the Software without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Software, and to -** permit persons to whom the Software is furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be -** included in all copies or substantial portions of the Software. -** -** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -** -****************************************************************************/ - -#include "qextserialport.h" -#include "qextserialport_p.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void QextSerialPortPrivate::platformSpecificInit() -{ - fd = 0; - readNotifier = 0; -} - -/*! - Standard destructor. -*/ -void QextSerialPortPrivate::platformSpecificDestruct() -{ -} - -static QString fullPortName(const QString &name) -{ - if (name.startsWith(QLatin1Char('/'))) - return name; - return QLatin1String("/dev/")+name; -} - -bool QextSerialPortPrivate::open_sys(QIODevice::OpenMode mode) -{ - Q_Q(QextSerialPort); - //note: linux 2.6.21 seems to ignore O_NDELAY flag - if ((fd = ::open(fullPortName(port).toLatin1() ,O_RDWR | O_NOCTTY | O_NDELAY)) != -1) { - - /*In the Private class, We can not call QIODevice::open()*/ - q->setOpenMode(mode); // Flag the port as opened - ::tcgetattr(fd, &oldTermios); // Save the old termios - currentTermios = oldTermios; // Make a working copy - ::cfmakeraw(¤tTermios); // Enable raw access - - /*set up other port settings*/ - currentTermios.c_cflag |= CREAD|CLOCAL; - currentTermios.c_lflag &= (~(ICANON|ECHO|ECHOE|ECHOK|ECHONL|ISIG)); - currentTermios.c_iflag &= (~(INPCK|IGNPAR|PARMRK|ISTRIP|ICRNL|IXANY)); - currentTermios.c_oflag &= (~OPOST); - currentTermios.c_cc[VMIN] = 0; -#ifdef _POSIX_VDISABLE // Is a disable character available on this system? - // Some systems allow for per-device disable-characters, so get the - // proper value for the configured device - const long vdisable = ::fpathconf(fd, _PC_VDISABLE); - currentTermios.c_cc[VINTR] = vdisable; - currentTermios.c_cc[VQUIT] = vdisable; - currentTermios.c_cc[VSTART] = vdisable; - currentTermios.c_cc[VSTOP] = vdisable; - currentTermios.c_cc[VSUSP] = vdisable; -#endif //_POSIX_VDISABLE - settingsDirtyFlags = DFE_ALL; - updatePortSettings(); - - if (queryMode == QextSerialPort::EventDriven) { - readNotifier = new QSocketNotifier(fd, QSocketNotifier::Read, q); - q->connect(readNotifier, SIGNAL(activated(int)), q, SLOT(_q_canRead())); - } - return true; - } else { - translateError(errno); - return false; - } -} - -bool QextSerialPortPrivate::close_sys() -{ - // Force a flush and then restore the original termios - flush_sys(); - // Using both TCSAFLUSH and TCSANOW here discards any pending input - ::tcsetattr(fd, TCSAFLUSH | TCSANOW, &oldTermios); // Restore termios - ::close(fd); - if (readNotifier) { - delete readNotifier; - readNotifier = 0; - } - return true; -} - -bool QextSerialPortPrivate::flush_sys() -{ - ::tcdrain(fd); - return true; -} - -qint64 QextSerialPortPrivate::bytesAvailable_sys() const -{ - int bytesQueued; - if (::ioctl(fd, FIONREAD, &bytesQueued) == -1) - return (qint64)-1; - return bytesQueued; -} - -/*! - Translates a system-specific error code to a QextSerialPort error code. Used internally. -*/ -void QextSerialPortPrivate::translateError(ulong error) -{ - switch (error) { - case EBADF: - case ENOTTY: - lastErr = E_INVALID_FD; - break; - case EINTR: - lastErr = E_CAUGHT_NON_BLOCKED_SIGNAL; - break; - case ENOMEM: - lastErr = E_NO_MEMORY; - break; - case EACCES: - lastErr = E_PERMISSION_DENIED; - break; - case EAGAIN: - lastErr = E_AGAIN; - break; - } -} - -void QextSerialPortPrivate::setDtr_sys(bool set) -{ - int status; - ::ioctl(fd, TIOCMGET, &status); - if (set) - status |= TIOCM_DTR; - else - status &= ~TIOCM_DTR; - ::ioctl(fd, TIOCMSET, &status); -} - -void QextSerialPortPrivate::setRts_sys(bool set) -{ - int status; - ::ioctl(fd, TIOCMGET, &status); - if (set) - status |= TIOCM_RTS; - else - status &= ~TIOCM_RTS; - ::ioctl(fd, TIOCMSET, &status); -} - -unsigned long QextSerialPortPrivate::lineStatus_sys() -{ - unsigned long Status=0, Temp=0; - ::ioctl(fd, TIOCMGET, &Temp); - if (Temp & TIOCM_CTS) Status |= LS_CTS; - if (Temp & TIOCM_DSR) Status |= LS_DSR; - if (Temp & TIOCM_RI) Status |= LS_RI; - if (Temp & TIOCM_CD) Status |= LS_DCD; - if (Temp & TIOCM_DTR) Status |= LS_DTR; - if (Temp & TIOCM_RTS) Status |= LS_RTS; - if (Temp & TIOCM_ST) Status |= LS_ST; - if (Temp & TIOCM_SR) Status |= LS_SR; - return Status; -} - -/*! - Reads a block of data from the serial port. This function will read at most maxSize bytes from - the serial port and place them in the buffer pointed to by data. Return value is the number of - bytes actually read, or -1 on error. - - \warning before calling this function ensure that serial port associated with this class - is currently open (use isOpen() function to check if port is open). -*/ -qint64 QextSerialPortPrivate::readData_sys(char *data, qint64 maxSize) -{ - int retVal = ::read(fd, data, maxSize); - if (retVal == -1) - lastErr = E_READ_FAILED; - - return retVal; -} - -/*! - Writes a block of data to the serial port. This function will write maxSize bytes - from the buffer pointed to by data to the serial port. Return value is the number - of bytes actually written, or -1 on error. - - \warning before calling this function ensure that serial port associated with this class - is currently open (use isOpen() function to check if port is open). -*/ -qint64 QextSerialPortPrivate::writeData_sys(const char *data, qint64 maxSize) -{ - int retVal = ::write(fd, data, maxSize); - if (retVal == -1) - lastErr = E_WRITE_FAILED; - - return (qint64)retVal; -} - -static void setBaudRate2Termios(termios *config, int baudRate) -{ -#ifdef CBAUD - config->c_cflag &= (~CBAUD); - config->c_cflag |= baudRate; -#else - ::cfsetispeed(config, baudRate); - ::cfsetospeed(config, baudRate); -#endif -} - -/* - All the platform settings was performed in this function. -*/ -void QextSerialPortPrivate::updatePortSettings() -{ - if (!q_func()->isOpen() || !settingsDirtyFlags) - return; - - if (settingsDirtyFlags & DFE_BaudRate) { - switch (settings.BaudRate) { - case BAUD50: - setBaudRate2Termios(¤tTermios, B50); - break; - case BAUD75: - setBaudRate2Termios(¤tTermios, B75); - break; - case BAUD110: - setBaudRate2Termios(¤tTermios, B110); - break; - case BAUD134: - setBaudRate2Termios(¤tTermios, B134); - break; - case BAUD150: - setBaudRate2Termios(¤tTermios, B150); - break; - case BAUD200: - setBaudRate2Termios(¤tTermios, B200); - break; - case BAUD300: - setBaudRate2Termios(¤tTermios, B300); - break; - case BAUD600: - setBaudRate2Termios(¤tTermios, B600); - break; - case BAUD1200: - setBaudRate2Termios(¤tTermios, B1200); - break; - case BAUD1800: - setBaudRate2Termios(¤tTermios, B1800); - break; - case BAUD2400: - setBaudRate2Termios(¤tTermios, B2400); - break; - case BAUD4800: - setBaudRate2Termios(¤tTermios, B4800); - break; - case BAUD9600: - setBaudRate2Termios(¤tTermios, B9600); - break; - case BAUD19200: - setBaudRate2Termios(¤tTermios, B19200); - break; - case BAUD38400: - setBaudRate2Termios(¤tTermios, B38400); - break; - case BAUD57600: - setBaudRate2Termios(¤tTermios, B57600); - break; -#ifdef B76800 - case BAUD76800: - setBaudRate2Termios(¤tTermios, B76800); - break; -#endif - case BAUD115200: - setBaudRate2Termios(¤tTermios, B115200); - break; -#if defined(B230400) && defined(B4000000) - case BAUD230400: - setBaudRate2Termios(¤tTermios, B230400); - break; - case BAUD460800: - setBaudRate2Termios(¤tTermios, B460800); - break; - case BAUD500000: - setBaudRate2Termios(¤tTermios, B500000); - break; - case BAUD576000: - setBaudRate2Termios(¤tTermios, B576000); - break; - case BAUD921600: - setBaudRate2Termios(¤tTermios, B921600); - break; - case BAUD1000000: - setBaudRate2Termios(¤tTermios, B1000000); - break; - case BAUD1152000: - setBaudRate2Termios(¤tTermios, B1152000); - break; - case BAUD1500000: - setBaudRate2Termios(¤tTermios, B1500000); - break; - case BAUD2000000: - setBaudRate2Termios(¤tTermios, B2000000); - break; - case BAUD2500000: - setBaudRate2Termios(¤tTermios, B2500000); - break; - case BAUD3000000: - setBaudRate2Termios(¤tTermios, B3000000); - break; - case BAUD3500000: - setBaudRate2Termios(¤tTermios, B3500000); - break; - case BAUD4000000: - setBaudRate2Termios(¤tTermios, B4000000); - break; -#endif -#ifdef Q_OS_MAC - default: - setBaudRate2Termios(¤tTermios, settings.BaudRate); - break; -#endif - } - } - if (settingsDirtyFlags & DFE_Parity) { - switch (settings.Parity) { - case PAR_SPACE: - /*space parity not directly supported - add an extra data bit to simulate it*/ - settingsDirtyFlags |= DFE_DataBits; - break; - case PAR_NONE: - currentTermios.c_cflag &= (~PARENB); - break; - case PAR_EVEN: - currentTermios.c_cflag &= (~PARODD); - currentTermios.c_cflag |= PARENB; - break; - case PAR_ODD: - currentTermios.c_cflag |= (PARENB|PARODD); - break; - } - } - /*must after Parity settings*/ - if (settingsDirtyFlags & DFE_DataBits) { - if (settings.Parity != PAR_SPACE) { - currentTermios.c_cflag &= (~CSIZE); - switch(settings.DataBits) { - case DATA_5: - currentTermios.c_cflag |= CS5; - break; - case DATA_6: - currentTermios.c_cflag |= CS6; - break; - case DATA_7: - currentTermios.c_cflag |= CS7; - break; - case DATA_8: - currentTermios.c_cflag |= CS8; - break; - } - } else { - /*space parity not directly supported - add an extra data bit to simulate it*/ - currentTermios.c_cflag &= ~(PARENB|CSIZE); - switch(settings.DataBits) { - case DATA_5: - currentTermios.c_cflag |= CS6; - break; - case DATA_6: - currentTermios.c_cflag |= CS7; - break; - case DATA_7: - currentTermios.c_cflag |= CS8; - break; - case DATA_8: - /*this will never happen, put here to Suppress an warning*/ - break; - } - } - } - if (settingsDirtyFlags & DFE_StopBits) { - switch (settings.StopBits) { - case STOP_1: - currentTermios.c_cflag &= (~CSTOPB); - break; - case STOP_2: - currentTermios.c_cflag |= CSTOPB; - break; - } - } - if (settingsDirtyFlags & DFE_Flow) { - switch(settings.FlowControl) { - case FLOW_OFF: - currentTermios.c_cflag &= (~CRTSCTS); - currentTermios.c_iflag &= (~(IXON|IXOFF|IXANY)); - break; - case FLOW_XONXOFF: - /*software (XON/XOFF) flow control*/ - currentTermios.c_cflag &= (~CRTSCTS); - currentTermios.c_iflag |= (IXON|IXOFF|IXANY); - break; - case FLOW_HARDWARE: - currentTermios.c_cflag |= CRTSCTS; - currentTermios.c_iflag &= (~(IXON|IXOFF|IXANY)); - break; - } - } - - /*if any thing in currentTermios changed, flush*/ - if (settingsDirtyFlags & DFE_Settings_Mask) - ::tcsetattr(fd, TCSAFLUSH, ¤tTermios); - - if (settingsDirtyFlags & DFE_TimeOut) { - int millisec = settings.Timeout_Millisec; - if (millisec == -1) { - ::fcntl(fd, F_SETFL, O_NDELAY); - } else { - //O_SYNC should enable blocking ::write() - //however this seems not working on Linux 2.6.21 (works on OpenBSD 4.2) - ::fcntl(fd, F_SETFL, O_SYNC); - } - ::tcgetattr(fd, ¤tTermios); - currentTermios.c_cc[VTIME] = millisec/100; - ::tcsetattr(fd, TCSAFLUSH, ¤tTermios); - } - - settingsDirtyFlags = 0; -} diff --git a/extserial/src/qextserialport_win.cpp b/extserial/src/qextserialport_win.cpp deleted file mode 100644 index 165dca8..0000000 --- a/extserial/src/qextserialport_win.cpp +++ /dev/null @@ -1,407 +0,0 @@ -/**************************************************************************** -** Copyright (c) 2000-2003 Wayne Roth -** Copyright (c) 2004-2007 Stefan Sander -** Copyright (c) 2007 Michal Policht -** Copyright (c) 2008 Brandon Fosdick -** Copyright (c) 2009-2010 Liam Staskawicz -** Copyright (c) 2011 Debao Zhang -** All right reserved. -** Web: http://code.google.com/p/qextserialport/ -** -** Permission is hereby granted, free of charge, to any person obtaining -** a copy of this software and associated documentation files (the -** "Software"), to deal in the Software without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Software, and to -** permit persons to whom the Software is furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be -** included in all copies or substantial portions of the Software. -** -** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -** -****************************************************************************/ - -#include "qextserialport.h" -#include "qextserialport_p.h" - -#include -#include -#include -#include -#include -#include -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) -# include -#else -# include -#endif -void QextSerialPortPrivate::platformSpecificInit() -{ - handle = INVALID_HANDLE_VALUE; - ZeroMemory(&overlap, sizeof(OVERLAPPED)); - overlap.hEvent = CreateEvent(NULL, true, false, NULL); - winEventNotifier = 0; - bytesToWriteLock = new QReadWriteLock; -} - -void QextSerialPortPrivate::platformSpecificDestruct() { - CloseHandle(overlap.hEvent); - delete bytesToWriteLock; -} - - -/*! - \internal - COM ports greater than 9 need \\.\ prepended - - This is only need when open the port. -*/ -static QString fullPortNameWin(const QString &name) -{ - QRegExp rx(QLatin1String("^COM(\\d+)")); - QString fullName(name); - if (fullName.contains(rx)) - fullName.prepend(QLatin1String("\\\\.\\")); - return fullName; -} - -bool QextSerialPortPrivate::open_sys(QIODevice::OpenMode mode) -{ - Q_Q(QextSerialPort); - DWORD confSize = sizeof(COMMCONFIG); - commConfig.dwSize = confSize; - DWORD dwFlagsAndAttributes = 0; - if (queryMode == QextSerialPort::EventDriven) - dwFlagsAndAttributes += FILE_FLAG_OVERLAPPED; - - /*open the port*/ - handle = CreateFileW((wchar_t *)fullPortNameWin(port).utf16(), GENERIC_READ|GENERIC_WRITE, - 0, NULL, OPEN_EXISTING, dwFlagsAndAttributes, NULL); - if (handle != INVALID_HANDLE_VALUE) { - q->setOpenMode(mode); - /*configure port settings*/ - GetCommConfig(handle, &commConfig, &confSize); - GetCommState(handle, &(commConfig.dcb)); - - /*set up parameters*/ - commConfig.dcb.fBinary = TRUE; - commConfig.dcb.fInX = FALSE; - commConfig.dcb.fOutX = FALSE; - commConfig.dcb.fAbortOnError = FALSE; - commConfig.dcb.fNull = FALSE; - /* Dtr default to true. See Issue 122*/ - commConfig.dcb.fDtrControl = TRUE; - /*flush all settings*/ - settingsDirtyFlags = DFE_ALL; - updatePortSettings(); - - //init event driven approach - if (queryMode == QextSerialPort::EventDriven) { - if (!SetCommMask(handle, EV_TXEMPTY | EV_RXCHAR | EV_DSR)) { - QESP_WARNING()<<"failed to set Comm Mask. Error code:"<("HANDLE"); - q->connect(winEventNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_onWinEvent(HANDLE)), Qt::DirectConnection); - WaitCommEvent(handle, &eventMask, &overlap); - } - return true; - } - return false; -} - -bool QextSerialPortPrivate::close_sys() -{ - flush_sys(); - CancelIo(handle); - if (CloseHandle(handle)) - handle = INVALID_HANDLE_VALUE; - if (winEventNotifier) { - winEventNotifier->setEnabled(false); - winEventNotifier->deleteLater(); - winEventNotifier = 0; - } - - foreach (OVERLAPPED *o, pendingWrites) { - CloseHandle(o->hEvent); - delete o; - } - pendingWrites.clear(); - return true; -} - -bool QextSerialPortPrivate::flush_sys() -{ - FlushFileBuffers(handle); - return true; -} - -qint64 QextSerialPortPrivate::bytesAvailable_sys() const -{ - DWORD Errors; - COMSTAT Status; - if (ClearCommError(handle, &Errors, &Status)) - return Status.cbInQue; - - return (qint64)-1; -} - -/* - Translates a system-specific error code to a QextSerialPort error code. Used internally. -*/ -void QextSerialPortPrivate::translateError(ulong error) -{ - if (error & CE_BREAK) { - lastErr = E_BREAK_CONDITION; - } else if (error & CE_FRAME) { - lastErr = E_FRAMING_ERROR; - } else if (error & CE_IOE) { - lastErr = E_IO_ERROR; - } else if (error & CE_MODE) { - lastErr = E_INVALID_FD; - } else if (error & CE_OVERRUN) { - lastErr = E_BUFFER_OVERRUN; - } else if (error & CE_RXPARITY) { - lastErr = E_RECEIVE_PARITY_ERROR; - } else if (error & CE_RXOVER) { - lastErr = E_RECEIVE_OVERFLOW; - } else if (error & CE_TXFULL) { - lastErr = E_TRANSMIT_OVERFLOW; - } -} - -/* - Reads a block of data from the serial port. This function will read at most maxlen bytes from - the serial port and place them in the buffer pointed to by data. Return value is the number of - bytes actually read, or -1 on error. - - \warning before calling this function ensure that serial port associated with this class - is currently open (use isOpen() function to check if port is open). -*/ -qint64 QextSerialPortPrivate::readData_sys(char *data, qint64 maxSize) -{ - DWORD bytesRead = 0; - bool failed = false; - if (queryMode == QextSerialPort::EventDriven) { - OVERLAPPED overlapRead; - ZeroMemory(&overlapRead, sizeof(OVERLAPPED)); - if (!ReadFile(handle, (void *)data, (DWORD)maxSize, &bytesRead, &overlapRead)) { - if (GetLastError() == ERROR_IO_PENDING) - GetOverlappedResult(handle, &overlapRead, &bytesRead, true); - else - failed = true; - } - } else if (!ReadFile(handle, (void *)data, (DWORD)maxSize, &bytesRead, NULL)) { - failed = true; - } - if (!failed) - return (qint64)bytesRead; - - lastErr = E_READ_FAILED; - return -1; -} - -/* - Writes a block of data to the serial port. This function will write len bytes - from the buffer pointed to by data to the serial port. Return value is the number - of bytes actually written, or -1 on error. - - \warning before calling this function ensure that serial port associated with this class - is currently open (use isOpen() function to check if port is open). -*/ -qint64 QextSerialPortPrivate::writeData_sys(const char *data, qint64 maxSize) -{ - DWORD bytesWritten = 0; - bool failed = false; - if (queryMode == QextSerialPort::EventDriven) { - OVERLAPPED *newOverlapWrite = new OVERLAPPED; - ZeroMemory(newOverlapWrite, sizeof(OVERLAPPED)); - newOverlapWrite->hEvent = CreateEvent(NULL, true, false, NULL); - if (WriteFile(handle, (void *)data, (DWORD)maxSize, &bytesWritten, newOverlapWrite)) { - CloseHandle(newOverlapWrite->hEvent); - delete newOverlapWrite; - } else if (GetLastError() == ERROR_IO_PENDING) { - // writing asynchronously...not an error - QWriteLocker writelocker(bytesToWriteLock); - pendingWrites.append(newOverlapWrite); - } else { - QESP_WARNING()<<"QextSerialPort write error:"<hEvent)) - QESP_WARNING("QextSerialPort: couldn't cancel IO"); - if (!CloseHandle(newOverlapWrite->hEvent)) - QESP_WARNING("QextSerialPort: couldn't close OVERLAPPED handle"); - delete newOverlapWrite; - } - } else if (!WriteFile(handle, (void *)data, (DWORD)maxSize, &bytesWritten, NULL)) { - failed = true; - } - - if (!failed) - return (qint64)bytesWritten; - - lastErr = E_WRITE_FAILED; - return -1; -} - -void QextSerialPortPrivate::setDtr_sys(bool set) { - EscapeCommFunction(handle, set ? SETDTR : CLRDTR); -} - -void QextSerialPortPrivate::setRts_sys(bool set) { - EscapeCommFunction(handle, set ? SETRTS : CLRRTS); -} - -ulong QextSerialPortPrivate::lineStatus_sys(void) { - unsigned long Status = 0, Temp = 0; - GetCommModemStatus(handle, &Temp); - if (Temp & MS_CTS_ON) Status |= LS_CTS; - if (Temp & MS_DSR_ON) Status |= LS_DSR; - if (Temp & MS_RING_ON) Status |= LS_RI; - if (Temp & MS_RLSD_ON) Status |= LS_DCD; - return Status; -} - -/* - Triggered when there's activity on our HANDLE. -*/ -void QextSerialPortPrivate::_q_onWinEvent(HANDLE h) -{ - Q_Q(QextSerialPort); - if (h == overlap.hEvent) { - if (eventMask & EV_RXCHAR) { - if (q->sender() != q && bytesAvailable_sys() > 0) - _q_canRead(); - } - if (eventMask & EV_TXEMPTY) { - /* - A write completed. Run through the list of OVERLAPPED writes, and if - they completed successfully, take them off the list and delete them. - Otherwise, leave them on there so they can finish. - */ - qint64 totalBytesWritten = 0; - QList overlapsToDelete; - QWriteLocker writelocker(bytesToWriteLock); - foreach (OVERLAPPED *o, pendingWrites) { - DWORD numBytes = 0; - if (GetOverlappedResult(handle, o, &numBytes, false)) { - overlapsToDelete.append(o); - totalBytesWritten += numBytes; - } else if (GetLastError() != ERROR_IO_INCOMPLETE) { - overlapsToDelete.append(o); - QESP_WARNING()<<"CommEvent overlapped write error:" << GetLastError(); - } - } - - if (q->sender() != q && totalBytesWritten > 0) - Q_EMIT q->bytesWritten(totalBytesWritten); - - foreach (OVERLAPPED *o, overlapsToDelete) { - OVERLAPPED *toDelete = pendingWrites.takeAt(pendingWrites.indexOf(o)); - CloseHandle(toDelete->hEvent); - delete toDelete; - } - } - if (eventMask & EV_DSR) { - if (lineStatus_sys() & LS_DSR) - Q_EMIT q->dsrChanged(true); - else - Q_EMIT q->dsrChanged(false); - } - } - WaitCommEvent(handle, &eventMask, &overlap); -} - -void QextSerialPortPrivate::updatePortSettings() -{ - if (!q_ptr->isOpen() || !settingsDirtyFlags) - return; - - //fill struct : COMMCONFIG - if (settingsDirtyFlags & DFE_BaudRate) - commConfig.dcb.BaudRate = settings.BaudRate; - if (settingsDirtyFlags & DFE_Parity) { - commConfig.dcb.Parity = (BYTE)settings.Parity; - commConfig.dcb.fParity = (settings.Parity == PAR_NONE) ? FALSE : TRUE; - } - if (settingsDirtyFlags & DFE_DataBits) - commConfig.dcb.ByteSize = (BYTE)settings.DataBits; - if (settingsDirtyFlags & DFE_StopBits) { - switch (settings.StopBits) { - case STOP_1: - commConfig.dcb.StopBits = ONESTOPBIT; - break; - case STOP_1_5: - commConfig.dcb.StopBits = ONE5STOPBITS; - break; - case STOP_2: - commConfig.dcb.StopBits = TWOSTOPBITS; - break; - } - } - if (settingsDirtyFlags & DFE_Flow) { - switch(settings.FlowControl) { - /*no flow control*/ - case FLOW_OFF: - commConfig.dcb.fOutxCtsFlow = FALSE; - commConfig.dcb.fRtsControl = RTS_CONTROL_DISABLE; - commConfig.dcb.fInX = FALSE; - commConfig.dcb.fOutX = FALSE; - break; - /*software (XON/XOFF) flow control*/ - case FLOW_XONXOFF: - commConfig.dcb.fOutxCtsFlow = FALSE; - commConfig.dcb.fRtsControl = RTS_CONTROL_DISABLE; - commConfig.dcb.fInX = TRUE; - commConfig.dcb.fOutX = TRUE; - break; - /*hardware flow control*/ - case FLOW_HARDWARE: - commConfig.dcb.fOutxCtsFlow = TRUE; - commConfig.dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; - commConfig.dcb.fInX = FALSE; - commConfig.dcb.fOutX = FALSE; - break; - } - } - - //fill struct : COMMTIMEOUTS - if (settingsDirtyFlags & DFE_TimeOut) { - if (queryMode != QextSerialPort::EventDriven) { - int millisec = settings.Timeout_Millisec; - if (millisec == -1) { - commTimeouts.ReadIntervalTimeout = MAXDWORD; - commTimeouts.ReadTotalTimeoutConstant = 0; - } else { - commTimeouts.ReadIntervalTimeout = millisec; - commTimeouts.ReadTotalTimeoutConstant = millisec; - } - commTimeouts.ReadTotalTimeoutMultiplier = 0; - commTimeouts.WriteTotalTimeoutMultiplier = millisec; - commTimeouts.WriteTotalTimeoutConstant = 0; - } else { - commTimeouts.ReadIntervalTimeout = MAXDWORD; - commTimeouts.ReadTotalTimeoutMultiplier = 0; - commTimeouts.ReadTotalTimeoutConstant = 0; - commTimeouts.WriteTotalTimeoutMultiplier = 0; - commTimeouts.WriteTotalTimeoutConstant = 0; - } - } - - - if (settingsDirtyFlags & DFE_Settings_Mask) - SetCommConfig(handle, &commConfig, sizeof(COMMCONFIG)); - if ((settingsDirtyFlags & DFE_TimeOut)) - SetCommTimeouts(handle, &commTimeouts); - settingsDirtyFlags = 0; -} - diff --git a/forms/qsstoast.ui b/forms/qsstoast.ui index 9d0aa15..813c0f0 100644 --- a/forms/qsstoast.ui +++ b/forms/qsstoast.ui @@ -10,6 +10,11 @@ 59 + + + Arial + + Form diff --git a/qsswraper.pri b/qsswraper.pri index 4f4aa74..7a32d58 100644 --- a/qsswraper.pri +++ b/qsswraper.pri @@ -2,7 +2,6 @@ INCLUDEPATH += $$PWD DEPENDPATH += $$PWD -include($$PWD/extserial/src/qextserialport.pri) HEADERS += $$PWD/Qss.h