/*!
\fn bool Win_QextSerialPort::open(OpenMode mode)
Opens a serial port.  Note that this function does not specify which device to open.  If you need
to open a device by name, see Win_QextSerialPort::open(const char*).  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 Win_QextSerialPort::open(OpenMode mode) {
	unsigned long confSize = sizeof(COMMCONFIG);
	Win_CommConfig.dwSize = confSize;
	DWORD dwFlagsAndAttributes = 0;
	if (queryMode() == QextSerialBase::EventDriven)
		dwFlagsAndAttributes += FILE_FLAG_OVERLAPPED;

    LOCK_MUTEX();
    if (mode == QIODevice::NotOpen)
        return isOpen();
    if (!isOpen()) {
        /*open the port*/
        Win_Handle=CreateFileA(port.toLatin1(), GENERIC_READ|GENERIC_WRITE,
                              FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, dwFlagsAndAttributes, NULL);
        if (Win_Handle!=INVALID_HANDLE_VALUE)
        {
            /*configure port settings*/
            GetCommConfig(Win_Handle, &Win_CommConfig, &confSize);
            GetCommState(Win_Handle, &(Win_CommConfig.dcb));

            /*set up parameters*/
            Win_CommConfig.dcb.fBinary=TRUE;
            Win_CommConfig.dcb.fInX=FALSE;
            Win_CommConfig.dcb.fOutX=FALSE;
            Win_CommConfig.dcb.fAbortOnError=FALSE;
            Win_CommConfig.dcb.fNull=FALSE;
            setBaudRate(Settings.BaudRate);
            setDataBits(Settings.DataBits);
            setStopBits(Settings.StopBits);
            setParity(Settings.Parity);
            setFlowControl(Settings.FlowControl);
            setTimeout(Settings.Timeout_Millisec);
            SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));

            //init event driven approach
			if (queryMode() == QextSerialBase::EventDriven) {
		        Win_CommTimeouts.ReadIntervalTimeout = MAXDWORD;
		        Win_CommTimeouts.ReadTotalTimeoutMultiplier = 0;
		        Win_CommTimeouts.ReadTotalTimeoutConstant = 0;
				Win_CommTimeouts.WriteTotalTimeoutMultiplier = 0;
				Win_CommTimeouts.WriteTotalTimeoutConstant = 0;
				SetCommTimeouts(Win_Handle, &Win_CommTimeouts);
            	if (!SetCommMask( Win_Handle, EV_TXEMPTY | EV_RXCHAR | EV_DSR)) {
            		qWarning("Failed to set Comm Mask. Error code: %ld", GetLastError());
					UNLOCK_MUTEX();
            		return false;
            	}
            	overlapThread->start();
            }
			QIODevice::open(mode);
        }
    } else {
		UNLOCK_MUTEX();
    	return false;
    }
    UNLOCK_MUTEX();
    return isOpen();
}
Esempio n. 2
0
/*!
Opens a serial port.  Note that this function does not specify which device to open.  If you need
to open a device by name, see QextSerialPort::open(const char*).  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) {
    unsigned long confSize = sizeof(COMMCONFIG);
    Win_CommConfig.dwSize = confSize;
    DWORD dwFlagsAndAttributes = 0;
    if (queryMode() == QextSerialPort::EventDriven)
        dwFlagsAndAttributes += FILE_FLAG_OVERLAPPED;

    QMutexLocker lock(mutex);
    if (mode == QIODevice::NotOpen)
        return isOpen();
    if (!isOpen()) {
        /*open the port*/
        Win_Handle=CreateFileA(port.toAscii(), GENERIC_READ|GENERIC_WRITE,
                              0, NULL, OPEN_EXISTING, dwFlagsAndAttributes, NULL);
        if (Win_Handle!=INVALID_HANDLE_VALUE) {
            QIODevice::open(mode);
            /*configure port settings*/
            GetCommConfig(Win_Handle, &Win_CommConfig, &confSize);
            GetCommState(Win_Handle, &(Win_CommConfig.dcb));

            /*set up parameters*/
            Win_CommConfig.dcb.fBinary=TRUE;
            Win_CommConfig.dcb.fInX=FALSE;
            Win_CommConfig.dcb.fOutX=FALSE;
            Win_CommConfig.dcb.fAbortOnError=FALSE;
            Win_CommConfig.dcb.fNull=FALSE;
            setBaudRate(Settings.BaudRate);
            setDataBits(Settings.DataBits);
            setStopBits(Settings.StopBits);
            setParity(Settings.Parity);
            setFlowControl(Settings.FlowControl);
            setTimeout(Settings.Timeout_Millisec);
            SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));

            //init event driven approach
            if (queryMode() == QextSerialPort::EventDriven) {
                Win_CommTimeouts.ReadIntervalTimeout = MAXDWORD;
                Win_CommTimeouts.ReadTotalTimeoutMultiplier = 0;
                Win_CommTimeouts.ReadTotalTimeoutConstant = 0;
                Win_CommTimeouts.WriteTotalTimeoutMultiplier = 0;
                Win_CommTimeouts.WriteTotalTimeoutConstant = 0;
                SetCommTimeouts(Win_Handle, &Win_CommTimeouts);
                if (!SetCommMask( Win_Handle, EV_TXEMPTY | EV_RXCHAR | EV_DSR)) {
                    qWarning() << "failed to set Comm Mask. Error code:", GetLastError();
                    return false;
                }
                winEventNotifier = new QWinEventNotifier(overlap.hEvent, this);
                connect(winEventNotifier, SIGNAL(activated(HANDLE)), this, SLOT(onWinEvent(HANDLE)));
                WaitCommEvent(Win_Handle, &eventMask, &overlap);
            }
        }
    } else {
        return false;
    }
    return isOpen();
}
Esempio n. 3
0
/*!
\fn qint64 Win_QextSerialPort::writeData(const char *data, qint64 maxSize)
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 Win_QextSerialPort::writeData(const char *data, qint64 maxSize)
{
	DWORD retVal;
	
    LOCK_MUTEX();

    retVal = 0;
    if (queryMode() == QextSerialBase::EventDriven) {
    	bytesToWriteLock->lockForWrite();
    	_bytesToWrite += maxSize;
    	bytesToWriteLock->unlock();
		overlapWrite.Internal = 0;
		overlapWrite.InternalHigh = 0;
		overlapWrite.Offset = 0;
		overlapWrite.OffsetHigh = 0;
		overlapWrite.hEvent = CreateEvent(NULL, true, false, NULL);
		if (!WriteFile(Win_Handle, (void*)data, (DWORD)maxSize, & retVal, & overlapWrite)) {
			lastErr = E_WRITE_FAILED;
			retVal = (DWORD)-1;
	   	} else
	   		retVal = maxSize;
    } else if (!WriteFile(Win_Handle, (void*)data, (DWORD)maxSize, & retVal, NULL)) {
		lastErr = E_WRITE_FAILED;
		retVal = (DWORD)-1;
   	}
   	
    UNLOCK_MUTEX();

    return (qint64)retVal;
}
Esempio n. 4
0
/*!
\fn qint64 Win_QextSerialPort::readData(char *data, qint64 maxSize)
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 Win_QextSerialPort::readData(char *data, qint64 maxSize)
{
    DWORD retVal;
	
    LOCK_MUTEX();
    
    retVal = 0;
	if (queryMode() == QextSerialBase::EventDriven) {
		OVERLAPPED overlapRead;
		overlapRead.Internal = 0;
		overlapRead.InternalHigh = 0;
		overlapRead.Offset = 0;
		overlapRead.OffsetHigh = 0;
		overlapRead.hEvent = CreateEvent(NULL, true, false, NULL);
		if (!ReadFile(Win_Handle, (void*)data, (DWORD)maxSize, & retVal, & overlapRead)) {
			if (GetLastError() == ERROR_IO_PENDING)
				GetOverlappedResult(Win_Handle, & overlapRead, & retVal, true);
			else {
	        	lastErr = E_READ_FAILED;
	        	retVal = (DWORD)-1;
			}
		}
		CloseHandle(overlapRead.hEvent);
	} else if (!ReadFile(Win_Handle, (void*)data, (DWORD)maxSize, & retVal, NULL)) {
        lastErr = E_READ_FAILED;
        retVal = (DWORD)-1;
    }

	UNLOCK_MUTEX();

    return (qint64)retVal;
}
Esempio n. 5
0
/*!
\fn void Win_QextSerialPort::setTimeout(ulong millisec);
Sets the read and write timeouts for the port to millisec milliseconds.
Setting 0 for both sec and millisec indicates that timeouts are not used for read nor
write operations. Setting -1 indicates that read and write should return immediately.

\note this function does nothing in event driven mode.
*/
void Win_QextSerialPort::setTimeout(long millisec) 
{
    LOCK_MUTEX();
    Settings.Timeout_Millisec = millisec;

    if (millisec == -1) 
    {
        m_WinCommTimeouts.ReadIntervalTimeout = MAXDWORD;
        m_WinCommTimeouts.ReadTotalTimeoutConstant = 0;
    } 
    else 
    {
        m_WinCommTimeouts.ReadIntervalTimeout = millisec;
        m_WinCommTimeouts.ReadTotalTimeoutConstant = millisec;
    }
    m_WinCommTimeouts.ReadTotalTimeoutMultiplier = 0;
    m_WinCommTimeouts.WriteTotalTimeoutMultiplier = millisec;
    m_WinCommTimeouts.WriteTotalTimeoutConstant = 0;

    if (queryMode() != QextSerialBase::EventDriven)
    {
        SetCommTimeouts(m_WinHandle, &m_WinCommTimeouts);
    }

    UNLOCK_MUTEX();
}
Esempio n. 6
0
QByteArray QUsbHid::readData(qint64 maxSize)
{
    QByteArray res(maxSize,0);
    int retVal;
    QMutexLocker lock(mutex);
    retVal = 0;
    if (queryMode() == QUsbHid::EventDriven && false) {

    } else{
        if(!handle) return false;
        int actLen = 0;
        int timeout = DEF_TIMEOUT;
        int errorCode = libusb_interrupt_transfer(handle, epForRead, (uint8_t*)res.data(), maxSize, &actLen, timeout);
        if(errorCode < 0) retVal = 0;
        else retVal = actLen;
        lastErr = errorCode;
        qDebug()<<res;
    }
    if(retVal == 0){
        res.clear();
    }else{
        res.resize(retVal);
    }
    return res;
}
/*!
Opens the serial port associated to this class.
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)
{
    QMutexLocker lock(mutex);
    if (mode == QIODevice::NotOpen)
        return isOpen();
    if (!isOpen()) {
        qDebug() << "trying to open file" << port.toAscii();
        //note: linux 2.6.21 seems to ignore O_NDELAY flag
        if ((fd = ::open(port.toAscii() ,O_RDWR | O_NOCTTY | O_NDELAY)) != -1) {
            qDebug("file opened succesfully");

            setOpenMode(mode);              // Flag the port as opened
            tcgetattr(fd, &old_termios);    // Save the old termios
            Posix_CommConfig = old_termios; // Make a working copy


            /* the equivelent of cfmakeraw() to enable raw access */
#ifdef HAVE_CFMAKERAW
            cfmakeraw(&Posix_CommConfig);   // Enable raw access
#else
            Posix_CommConfig.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP
                                    | INLCR | IGNCR | ICRNL | IXON);
            Posix_CommConfig.c_oflag &= ~OPOST;
            Posix_CommConfig.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
            Posix_CommConfig.c_cflag &= ~(CSIZE | PARENB);
            Posix_CommConfig.c_cflag |= CS8;
#endif

            /*set up other port settings*/
            Posix_CommConfig.c_cflag|=CREAD|CLOCAL;
            Posix_CommConfig.c_lflag&=(~(ICANON|ECHO|ECHOE|ECHOK|ECHONL|ISIG));
            Posix_CommConfig.c_iflag&=(~(INPCK|IGNPAR|PARMRK|ISTRIP|ICRNL|IXANY));
            Posix_CommConfig.c_oflag&=(~OPOST);
            Posix_CommConfig.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);
            Posix_CommConfig.c_cc[VINTR] = vdisable;
            Posix_CommConfig.c_cc[VQUIT] = vdisable;
            Posix_CommConfig.c_cc[VSTART] = vdisable;
            Posix_CommConfig.c_cc[VSTOP] = vdisable;
            Posix_CommConfig.c_cc[VSUSP] = vdisable;
#endif //_POSIX_VDISABLE
            setBaudRate(Settings.BaudRate);
            setDataBits(Settings.DataBits);
            setParity(Settings.Parity);
            setStopBits(Settings.StopBits);
            setFlowControl(Settings.FlowControl);
            setTimeout(Settings.Timeout_Millisec);
            tcsetattr(fd, TCSAFLUSH, &Posix_CommConfig);

            if (queryMode() == QextSerialPort::EventDriven) {
                readNotifier = new QSocketNotifier(fd, QSocketNotifier::Read, this);
                connect(readNotifier, SIGNAL(activated(int)), this, SIGNAL(readyRead()));
            }
Esempio n. 8
0
static uint8_t parseUpload(uint8_t* buff, uint32_t len)
{
    uint8_t i = 0;
    uint8_t ret = 0;

    if(len < 6) return 0;

    group = buff[4];
    cmd 	= buff[5];
    for(; i < 4; i++)
    {
        if( (buff[i] != Terminal_ID[i] ) && (cmd != CMD_BROADCAST_DEVID))
            break;
    }
    if(i != 4) return 0 ;



    switch(cmd)
    {
    case CMD_UPLOAD_REQ:
        ret = parseUploadReq( buf2uint16(buff+6) , buf2uint32(buff+8));
        break;
    case CMD_UPLOAD_DATA:
    {

        uint16_t sid = buf2uint16(buff+6);
        uint16_t idx = buf2uint16(buff+8);
        ret = parseUploadData(sid,idx,buff+10, len-10);
        break;
    }

    case CMD_UPLOAD_VERIFY:
        ret = parseUploadVerify(buf2uint16(buff+6),buf2uint16(buff+8));
        break;
    case CMD_RESET:
        quit = 1;
        break;
    case CMD_BROADCAST_DEVID:
        ret = broadCastDeviceID();
        break;
	case CMD_QUERY_MODE:
		ret = queryMode(CMD_QUERY_MODE,ERR_OK);
		break;
    default:
        break;
    }

    return ret;
}
Esempio n. 9
0
int QextSerialPort::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
    _id = QIODevice::qt_metacall(_c, _id, _a);
    if (_id < 0)
        return _id;
    if (_c == QMetaObject::InvokeMetaMethod) {
        if (_id < 15)
            qt_static_metacall(this, _c, _id, _a);
        _id -= 15;
    } else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
        if (_id < 15)
            *reinterpret_cast<int*>(_a[0]) = -1;
        _id -= 15;
    }
#ifndef QT_NO_PROPERTIES
      else if (_c == QMetaObject::ReadProperty) {
        void *_v = _a[0];
        switch (_id) {
        case 0: *reinterpret_cast< QString*>(_v) = portName(); break;
        case 1: *reinterpret_cast< QueryMode*>(_v) = queryMode(); break;
        }
        _id -= 2;
    } else if (_c == QMetaObject::WriteProperty) {
        void *_v = _a[0];
        switch (_id) {
        case 0: setPortName(*reinterpret_cast< QString*>(_v)); break;
        case 1: setQueryMode(*reinterpret_cast< QueryMode*>(_v)); break;
        }
        _id -= 2;
    } else if (_c == QMetaObject::ResetProperty) {
        _id -= 2;
    } else if (_c == QMetaObject::QueryPropertyDesignable) {
        _id -= 2;
    } else if (_c == QMetaObject::QueryPropertyScriptable) {
        _id -= 2;
    } else if (_c == QMetaObject::QueryPropertyStored) {
        _id -= 2;
    } else if (_c == QMetaObject::QueryPropertyEditable) {
        _id -= 2;
    } else if (_c == QMetaObject::QueryPropertyUser) {
        _id -= 2;
    } else if (_c == QMetaObject::RegisterPropertyMetaType) {
        if (_id < 2)
            *reinterpret_cast<int*>(_a[0]) = -1;
        _id -= 2;
    }
#endif // QT_NO_PROPERTIES
    return _id;
}
void Posix_QextSerialPort::init()
{
	if (queryMode() == QextSerialBase::EventDriven)
		qWarning("POSIX doesn't have event driven mechanism implemented yet");
}
Esempio n. 11
0
bool QUsbHid::open(OpenMode mode)
{
    if (queryMode() == QUsbHid::EventDriven)
    QMutexLocker lock(mutex);
    if (mode == QIODevice::NotOpen)
        return isOpen();
    libusb_device* dev = QUsbHidEnumerator::get_device(this->m_path);
    if(!dev){
        return false;
    }

    libusb_get_device_descriptor(dev, &device_desc);

    lastErr = libusb_open(dev, &handle);
    if(lastErr < 0 ){
        if(lastErr == LIBUSB_ERROR_ACCESS){
            //qDebug()<<"Permission denied, run the following command in root mode";
            QString str = QString("echo SUBSYSTEM==\\\"usb\\\", ATTRS{idVendor}==\\\"%1\\\", ATTRS{idProduct}==\\\"%2\\\", MODE=\\\"0666\\\" > /etc/udev/rules.d/90-lxyppc.rules");
            str = str.arg(device_desc.idVendor,4,16,QChar('0')).arg(device_desc.idProduct,4,16,QChar('0'));
            //qDebug()<<str;
            permissionError = "\r\nTry run follow command as root\r\n";
            permissionError += str;
        }
        handle = 0;
    }


    if (handle != 0) {
        //HidD_GetPreparsedData (Win_Handle, &hidPrepParsedData);
        //HidP_GetCaps (hidPrepParsedData, &hidCaps);
        // here we should parse the report descriptor
        //init event driven approach
        hidCaps.featureReportLength = 64;
        hidCaps.inputReportLength = 64;
        hidCaps.outputReportLength = 64;
        hidCaps.uasgePage = 0;
        hidCaps.usage = 0;

        libusb_config_descriptor* cfg;
        int r = libusb_get_config_descriptor(dev,0, &cfg);

        if(r == 0){
            for(int j=0; j<cfg->bNumInterfaces; j++){
                const struct libusb_interface_descriptor * interface_desc = cfg->interface->altsetting+j;
                if(interface_desc->bInterfaceClass == LIBUSB_CLASS_HID){
                    for(int i=0;i<interface_desc->bNumEndpoints;i++){
                        const libusb_endpoint_descriptor* ep = cfg->interface->altsetting->endpoint+i;
                        if(ep->bEndpointAddress & 0x80){
                            hidCaps.inputReportLength = ep->wMaxPacketSize;
                            epForRead = ep->bEndpointAddress;
                        }else{
                            epForWrite = ep->bEndpointAddress;
                            hidCaps.outputReportLength = ep->wMaxPacketSize;
                        }
                    }
                    interface = j;
                    break;
                }
                // interface class must be LIBUSB_CLASS_HID
            }
            libusb_free_config_descriptor(cfg);
        }

        if(interface<0){
            lastErr = ERROR_DEVICE_NOT_SUPPORT;
        }else{

            lastErr = libusb_detach_kernel_driver(handle, 0);

            lastErr = libusb_set_configuration(handle, 1);

            lastErr = libusb_claim_interface(handle, interface);
            if(lastErr >= 0){
                QIODevice::open(mode);
                //epForRead = 0x81;
                //epForWrite = 0x01;
                if (queryMode() == QUsbHid::EventDriven) {
                    //winEventNotifier = new QWinEventNotifier(overlap.hEvent, this);
                    //connect(winEventNotifier, SIGNAL(activated(HANDLE)), this, SLOT(onWinEvent(HANDLE)));
                    //rawData[0] = 0;
                    //::ReadFile(Win_Handle, rawData, hidCaps.InputReportByteLength, 0, &overlap);
                    worker = new QHidWorker(this);
                    worker->start();
                }

            }else{
                libusb_close(handle);
            }
        }
    }
    m_isOpen = isOpen();
    return isOpen();
}