bool directx_camera_server::open_and_find_parameters( std::string const &pathPrefix, FilterOperation const &sourceConfig, unsigned width, unsigned height) { auto graphbuilderRet = start_com_and_graphbuilder(); if (!graphbuilderRet) { return false; } auto pMoniker = find_first_capture_device_where([&pathPrefix](IMoniker &mon) { auto props = PropertyBagHelper{mon}; if (!props) { return false; } auto path = getDevicePath(props); if (path.length() < pathPrefix.length()) { return false; } return (path.substr(0, pathPrefix.length()) == pathPrefix); }); if (!pMoniker) { fprintf(stderr, "directx_camera_server::open_and_find_parameters(): " "Could not get the device requested - not enough " "cameras?\n"); return false; } #ifdef DEBUG std::cout << "directx_camera_server::open_and_find_parameters(): Accepted!" << std::endl; #endif return open_moniker_and_finish_setup(pMoniker, sourceConfig, width, height); }
void open(unsigned int port) { const std::string devicePath = getDevicePath(port); if (devicePath.empty()) { throw IOException(Poco::format("Failed to open usb port (index: %u).\n" "USB Interface not exist or already opened", port)); } handle_ = hid_open_path(devicePath.c_str()); if (!handle_) { throw IOException(Poco::format("Failed to open usb port (index: %u).\n" "USB Interface not exist or already opened", port)); } port_ = port; const UsbDeviceInfo& deviceInfo = getDeviceInfo(port); vendorId_ = deviceInfo.getVendorId(); productId_ = deviceInfo.getProductId(); manufacturer_ = deviceInfo.getManufacturer(); product_ = deviceInfo.getProduct(); serialNumber_ = deviceInfo.getSerialNumber(); }
SerialDevice * serialOpenDevice (const char *identifier) { char **parameters = serialGetDeviceParameters(identifier); if (parameters) { SerialDevice *serial; if ((serial = malloc(sizeof(*serial)))) { char *path; { const char *name = parameters[SERIAL_DEV_NAME]; if (!*name) name = SERIAL_FIRST_DEVICE; path = getDevicePath(name); } if (path) { int connected; serial->fileDescriptor = -1; serial->stream = NULL; connected = serialConnectDevice(serial, path); free(path); path = NULL; if (connected) { int ok = 1; if (!serialConfigureBaud(serial, parameters[SERIAL_DEV_BAUD])) ok = 0; if (!serialConfigureDataBits(serial, parameters[SERIAL_DEV_DATA_BITS])) ok = 0; if (!serialConfigureStopBits(serial, parameters[SERIAL_DEV_STOP_BITS])) ok = 0; if (!serialConfigureParity(serial, parameters[SERIAL_DEV_PARITY])) ok = 0; if (!serialConfigureFlowControl(serial, parameters[SERIAL_DEV_FLOW_CONTROL])) ok = 0; deallocateStrings(parameters); if (ok) return serial; serialCloseDevice(serial); return NULL; } } free(serial); } else { logMallocError(); } deallocateStrings(parameters); } return NULL; }
int InputDriverAbstract::openDevice() { if (mDeviceStatus == IDS_OPENED) { return 1; } if (mFileDescriptor == -1 || mFileDescriptor == 0) { mFileDescriptor = open(getDevicePath(), O_RDWR); // | O_NONBLOCK | O_EXCL if (mFileDescriptor == -1) { perror("InputDriverAbstract::openDevice(): open device"); return -1; } } mDeviceStatus = IDS_OPENED; return 0; }
const char * resolveDeviceName (const char *const *names, const char *description) { const char *first = *names; const char *device = NULL; const char *name; while ((name = *names++)) { char *path = getDevicePath(name); if (!path) break; logMessage(LOG_DEBUG, "checking %s device: %s", description, path); if (testPath(path)) { device = name; free(path); break; } logMessage(LOG_DEBUG, "%s device access error: %s: %s", description, path, strerror(errno)); if (errno != ENOENT) if (!device) device = name; free(path); } if (!device) { if (first) { device = first; } else { logMessage(LOG_ERR, "%s device names not defined", description); } } if (device) logMessage(LOG_INFO, "%s device: %s", description, device); return device; }
bool directx_camera_server::open_moniker_and_finish_setup( comutils::Ptr<IMoniker> pMoniker, FilterOperation const &sourceConfig, unsigned width, unsigned height) { if (!pMoniker) { fprintf(stderr, "directx_camera_server::open_moniker_and_finish_setup(): " "Null device moniker passed: no device found?\n"); return false; } auto prop = PropertyBagHelper{*pMoniker}; printf("directx_camera_server: Using capture device '%s' at path '%s'\n", getDeviceHumanDesc(prop).c_str(), getDevicePath(prop).c_str()); // Bind the chosen moniker to a filter object. auto pSrc = comutils::Ptr<IBaseFilter>{}; pMoniker->BindToObject(nullptr, nullptr, IID_IBaseFilter, AttachPtr(pSrc)); //------------------------------------------------------------------- // Construct the sample grabber that will be used to snatch images from // the video stream as they go by. Set its media type and callback. // Create and configure the Sample Grabber. _pSampleGrabberWrapper.reset(new SampleGrabberWrapper); // Get the exchange object for receiving data from the sample grabber. sampleExchange_ = _pSampleGrabberWrapper->getExchange(); //------------------------------------------------------------------- // Ask for the video resolution that has been passed in. // This code is based on // intuiting that we need to use the SetFormat call on the IAMStreamConfig // interface; this interface is described in the help pages. // If the width and height are specified as 0, then they are not set // in the header, letting them use whatever is the default. /// @todo factor this out into its own header. if ((width != 0) && (height != 0)) { auto pStreamConfig = comutils::Ptr<IAMStreamConfig>{}; _pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, pSrc.get(), IID_IAMStreamConfig, AttachPtr(pStreamConfig)); checkForConstructionError(pStreamConfig, "StreamConfig interface"); AM_MEDIA_TYPE mt = {0}; mt.majortype = MEDIATYPE_Video; // Ask for video media producers mt.subtype = MEDIASUBTYPE_RGB24; // Ask for 8 bit RGB VIDEOINFOHEADER vih = {0}; mt.pbFormat = reinterpret_cast<BYTE *>(&vih); auto pVideoHeader = &vih; pVideoHeader->bmiHeader.biBitCount = 24; pVideoHeader->bmiHeader.biWidth = width; pVideoHeader->bmiHeader.biHeight = height; pVideoHeader->bmiHeader.biPlanes = 1; pVideoHeader->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); pVideoHeader->bmiHeader.biSizeImage = dibsize(pVideoHeader->bmiHeader); // Set the format type and size. mt.formattype = FORMAT_VideoInfo; mt.cbFormat = sizeof(VIDEOINFOHEADER); // Set the sample size. mt.bFixedSizeSamples = TRUE; mt.lSampleSize = dibsize(pVideoHeader->bmiHeader); // Make the call to actually set the video type to what we want. if (pStreamConfig->SetFormat(&mt) != S_OK) { fprintf(stderr, "directx_camera_server::open_and_find_parameters():" " Can't set resolution to %dx%d using uncompressed " "24-bit video\n", pVideoHeader->bmiHeader.biWidth, pVideoHeader->bmiHeader.biHeight); return false; } } //------------------------------------------------------------------- // Create a null renderer that will be used to discard the video frames // on the output pin of the sample grabber #ifdef DEBUG printf("directx_camera_server::open_and_find_parameters(): Before " "createNullRenderFilter\n"); #endif auto pNullRender = createNullRenderFilter(); auto sampleGrabberFilter = _pSampleGrabberWrapper->getFilter(); //------------------------------------------------------------------- // Build the filter graph. First add the filters and then connect them. // pSrc is the capture filter for the video device we found above. auto hr = _pGraph->AddFilter(pSrc.get(), L"Video Capture"); BOOST_ASSERT_MSG(SUCCEEDED(hr), "Adding Video Capture filter to graph"); // Add the sample grabber filter hr = _pGraph->AddFilter(sampleGrabberFilter.get(), L"SampleGrabber"); BOOST_ASSERT_MSG(SUCCEEDED(hr), "Adding SampleGrabber filter to graph"); // Add the null renderer filter hr = _pGraph->AddFilter(pNullRender.get(), L"NullRenderer"); BOOST_ASSERT_MSG(SUCCEEDED(hr), "Adding NullRenderer filter to graph"); // Connect the output of the video reader to the sample grabber input ConnectTwoFilters(*_pGraph, *pSrc, *sampleGrabberFilter); // Connect the output of the sample grabber to the null renderer input ConnectTwoFilters(*_pGraph, *sampleGrabberFilter, *pNullRender); // If we were given a config action for the source, do it now. if (sourceConfig) { sourceConfig(*pSrc); } //------------------------------------------------------------------- // XXX See if this is a video tuner card by querying for that interface. // Set it to read the video channel if it is one. auto pTuner = comutils::Ptr<IAMTVTuner>{}; hr = _pBuilder->FindInterface(nullptr, nullptr, pSrc.get(), IID_IAMTVTuner, AttachPtr(pTuner)); if (pTuner) { #ifdef DEBUG printf("directx_camera_server::open_and_find_parameters(): Found a TV " "Tuner!\n"); #endif // XXX Put code here. // Set the first input pin to use the cable as input hr = pTuner->put_InputType(0, TunerInputCable); if (FAILED(hr)) { fprintf(stderr, "directx_camera_server::open_and_find_parameters():" " Can't set input to cable\n"); } // Set the channel on the video to be baseband (is this channel zero?) hr = pTuner->put_Channel(0, -1, -1); if (FAILED(hr)) { fprintf(stderr, "directx_camera_server::open_and_find_parameters():" " Can't set channel\n"); } } //------------------------------------------------------------------- // Find _num_rows and _num_columns in the video stream. AM_MEDIA_TYPE mt = {0}; _pSampleGrabberWrapper->getConnectedMediaType(mt); VIDEOINFOHEADER *pVih; if (mt.formattype == FORMAT_VideoInfo || mt.formattype == FORMAT_VideoInfo2) { pVih = reinterpret_cast<VIDEOINFOHEADER *>(mt.pbFormat); } else { fprintf(stderr, "directx_camera_server::open_and_find_parameters(): " "Can't get video header type\n"); fprintf(stderr, " (Expected %x or %x, got %x)\n", FORMAT_VideoInfo, FORMAT_VideoInfo2, mt.formattype); fprintf(stderr, " (GetConnectedMediaType is not valid for DirectX " "headers later than version 7)\n"); fprintf(stderr, " (We need to re-implement reading video in some " "other interface)\n"); return false; } // Number of rows and columns. This is different if we are using a target // rectangle (rcTarget) than if we are not. if (IsRectEmpty(&pVih->rcTarget)) { _num_columns = pVih->bmiHeader.biWidth; _num_rows = pVih->bmiHeader.biHeight; } else { _num_columns = pVih->rcTarget.right; _num_rows = pVih->bmiHeader.biHeight; printf("XXX directx_camera_server::open_and_find_parameters(): " "Warning: may not work correctly with target rectangle\n"); } #ifdef DEBUG printf("Got %dx%d video\n", _num_columns, _num_rows); #endif // Make sure that the image is not compressed and that we have 8 bits // per pixel. if (pVih->bmiHeader.biCompression != BI_RGB) { fprintf(stderr, "directx_camera_server::open_and_find_parameters(): " "Compression not RGB\n"); switch (pVih->bmiHeader.biCompression) { case BI_RLE8: fprintf(stderr, " (It is BI_RLE8)\n"); break; case BI_RLE4: fprintf(stderr, " (It is BI_RLE4)\n"); case BI_BITFIELDS: fprintf(stderr, " (It is BI_BITFIELDS)\n"); break; default: fprintf(stderr, " (Unknown compression type)\n"); } return false; } int BytesPerPixel = pVih->bmiHeader.biBitCount / 8; if (BytesPerPixel != 3) { fprintf(stderr, "directx_camera_server::open_and_find_parameters(): " "Not 3 bytes per pixel (%d)\n", pVih->bmiHeader.biBitCount); return false; } // A negative height indicates that the images are stored non-inverted in Y // Not sure what to do with images that have negative height -- need to // read the book some more to find out. if (_num_rows < 0) { fprintf(stderr, "directx_camera_server::open_and_find_parameters(): " "Num Rows is negative (internal error)\n"); return false; } // Find the stride to take when moving from one row of video to the // next. This is rounded up to the nearest DWORD. _stride = (_num_columns * BytesPerPixel + 3) & ~3; return true; }
inline comutils::Ptr<IMoniker> find_first_capture_device_where(F &&f) { auto ret = comutils::Ptr<IMoniker>{}; // Create the system device enumerator. #ifdef DEBUG printf("find_first_capture_device_where(): Before " "CoCreateInstance SystemDeviceEnum\n"); #endif auto pDevEnum = comutils::Ptr<ICreateDevEnum>{}; CoCreateInstance(CLSID_SystemDeviceEnum, nullptr, CLSCTX_INPROC, IID_ICreateDevEnum, AttachPtr(pDevEnum)); if (didConstructionFail(pDevEnum, "device enumerator")) { return ret; } // Create an enumerator for video capture devices. // https://msdn.microsoft.com/en-us/library/windows/desktop/dd407292(v=vs.85).aspx #ifdef DEBUG printf("find_first_capture_device_where(): Before " "CreateClassEnumerator\n"); #endif auto pClassEnum = comutils::Ptr<IEnumMoniker>{}; pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, AttachPtr(pClassEnum), 0); if (didConstructionFail(pClassEnum, "video enumerator (no cameras?)")) { return ret; } #ifdef DEBUG printf("find_first_capture_device_where(): Before Loop " "over enumerators\n"); #endif // see // https://msdn.microsoft.com/en-us/library/windows/desktop/dd377566(v=vs.85).aspx // for how to choose a camera #ifdef VERBOSE_ENUM printf("\ndirectx_camera_server find_first_capture_device_where(): " "Beginning enumeration of video capture devices.\n\n"); #endif auto pMoniker = comutils::Ptr<IMoniker>{}; while (pClassEnum->Next(1, AttachPtr(pMoniker), nullptr) == S_OK) { #ifdef VERBOSE_ENUM printf("- '%s' at path:\n '%s'\n\n", getDeviceHumanDesc(*pMoniker).c_str(), getDevicePath(*pMoniker).c_str()); #endif // VERBOSE_ENUM if (!ret && f(*pMoniker)) { ret = pMoniker; #ifdef VERBOSE_ENUM printf("^^ Accepted that device! (Would have exited " "enumeration here if VERBOSE_ENUM were not defined)\n\n"); #else // !VERBOSE_ENUM return ret; // Early out if we find it and we're not in verbose enum // mode. #endif } } #ifdef VERBOSE_ENUM printf("\ndirectx_camera_server find_first_capture_device_where(): End " "enumeration.\n\n"); #endif #ifdef DXCAMSERVER_VERBOSE if (!ret) { fprintf(stderr, "directx_camera_server find_first_capture_device_where(): " "No device satisfied the predicate.\n"); } #endif return ret; }
/*! \brief Enumerate Xsens USB devices If the OS already has drivers running for a device, the device should already have been found by xsEnumerateSerialPorts(). \param[in,out] ports The list of serial ports to append to */ bool xsEnumerateUsbDevices(XsPortInfoList& ports) { XsPortInfo current; #ifdef USE_WINUSB BOOL bResult = FALSE; ULONG length; ULONG requiredLength=0; // {FD51225C-700A-47e5-9999-B2D9031B88ED} GUID guid = { 0xfd51225c, 0x700a, 0x47e5, { 0x99, 0x99, 0xb2, 0xd9, 0x3, 0x1b, 0x88, 0xed } }; HDEVINFO deviceInfo; SP_DEVICE_INTERFACE_DATA interfaceData; PSP_DEVICE_INTERFACE_DETAIL_DATA_A detailData = NULL; deviceInfo = SetupDiGetClassDevs(&guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); // Initialize variables. interfaceData.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA); int port = 0; //lint --e{441} irregular for loop for (DWORD dwIndex = 0; port == 0; ++dwIndex) { BOOL bRet = SetupDiEnumDeviceInterfaces( deviceInfo, NULL, &guid, dwIndex, &interfaceData); if (!bRet) { if (GetLastError() == ERROR_NO_MORE_ITEMS) break; } else { if (!SetupDiGetDeviceInterfaceDetail(deviceInfo, &interfaceData, NULL, 0, &requiredLength, NULL)) { if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { SetupDiDestroyDeviceInfoList(deviceInfo); return false; } } detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA_A)LocalAlloc(LMEM_FIXED, requiredLength); if (NULL == detailData) { SetupDiDestroyDeviceInfoList(deviceInfo); return false; } detailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A); length = requiredLength; SP_DEVINFO_DATA DevInfoData; DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA); bResult = SetupDiGetDeviceInterfaceDetailA(deviceInfo, &interfaceData, detailData, length, &requiredLength, &DevInfoData); if (!bResult) { LocalFree(detailData); SetupDiDestroyDeviceInfoList(deviceInfo); return false; } unsigned char serialNumber[256]; char* ptrEnd, *ptrStart = strchr(detailData->DevicePath, '#'); if (!ptrStart) continue; ptrStart = strchr(ptrStart+1, '#'); if (!ptrStart) continue; ptrEnd = strchr(ptrStart+1, '#'); if (!ptrEnd) continue; strncpy((char*)serialNumber, ptrStart+1, ptrEnd-ptrStart-1); serialNumber[ptrEnd-ptrStart-1] = '\0'; current.setPortName(detailData->DevicePath); int id = 0; sscanf((const char *)serialNumber, "%X", &id); current.setDeviceId((uint32_t) id); std::string devpath = getDevicePath(deviceInfo, &DevInfoData); uint16_t vid = vidFromDevPath(devpath); uint16_t pid = pidFromDevPath(devpath); current.setVidPid(vid, pid); ports.push_back(current); } } SetupDiDestroyDeviceInfoList(deviceInfo); return true; #elif defined(HAVE_LIBUSB) XsLibUsb libUsb; libusb_context *context; int result = libUsb.init(&context); if (result != LIBUSB_SUCCESS) return true; libusb_device **deviceList; ssize_t deviceCount = libUsb.get_device_list(context, &deviceList); for (ssize_t i = 0; i < deviceCount; i++) { libusb_device *device = deviceList[i]; libusb_device_descriptor desc; result = libUsb.get_device_descriptor(device, &desc); if (result != LIBUSB_SUCCESS) continue; if (desc.idVendor != XSENS_VENDOR_ID && desc.idVendor != ATMEL_VENDOR_ID) continue; libusb_device_handle *handle; result = libUsb.open(device, &handle); if (result != LIBUSB_SUCCESS) continue; unsigned char serialNumber[256]; result = libUsb.get_string_descriptor_ascii(handle, desc.iSerialNumber, serialNumber, 256); if (desc.idVendor == ATMEL_VENDOR_ID && desc.idProduct == ATMEL_BORROWED_PRODUCT_ID) { unsigned char productName[256]; result = libUsb.get_string_descriptor_ascii(handle, desc.iProduct, productName, 256); if (strcmp("Xsens COM port", (const char *)productName) != 0) { libUsb.close(handle); continue; } } libusb_config_descriptor *configDesc; result = libUsb.get_active_config_descriptor(device, &configDesc); if (result != LIBUSB_SUCCESS) { libUsb.close(handle); continue; } bool kernelActive = false; for (uint8_t ifCount = 0; ifCount < configDesc->bNumInterfaces; ++ifCount) { int res = libUsb.kernel_driver_active(handle, ifCount); kernelActive |= (res == 1); } libUsb.free_config_descriptor(configDesc); if (!kernelActive) { char name[256]; sprintf(name, "USB%03u:%03u", libUsb.get_bus_number(device), libUsb.get_device_address(device)); current.setPortName(name); int id = 0; sscanf((const char *)serialNumber, "%X", &id); current.setDeviceId((uint32_t) id); current.setVidPid(desc.idVendor, desc.idProduct); ports.push_back(current); } else { JLDEBUG(gJournal, "Kernel driver active on USB" << libUsb.get_bus_number(device) << ":" << libUsb.get_device_address(device) << " device " << serialNumber); } libUsb.close(handle); } libUsb.free_device_list(deviceList, 1); libUsb.exit(context); return true; #else (void)ports; return false; #endif }
int openCharacterDevice (const char *name, int flags, int major, int minor) { char *path = getDevicePath(name); int descriptor; if (!path) { descriptor = -1; } else if ((descriptor = open(path, flags)) != -1) { logMessage(LOG_DEBUG, "device opened: %s: fd=%d", path, descriptor); } else { logMessage(LOG_DEBUG, "cannot open device: %s: %s", path, strerror(errno)); if (errno == ENOENT) { free(path); if ((path = makeWritablePath(locatePathName(name)))) { if ((descriptor = open(path, flags)) != -1) { logMessage(LOG_DEBUG, "device opened: %s: fd=%d", path, descriptor); } else { logMessage(LOG_DEBUG, "cannot open device: %s: %s", path, strerror(errno)); if (errno == ENOENT) { mode_t mode = S_IFCHR | S_IRUSR | S_IWUSR; if (mknod(path, mode, makedev(major, minor)) == -1) { logMessage(LOG_DEBUG, "cannot create device: %s: %s", path, strerror(errno)); } else { logMessage(LOG_DEBUG, "device created: %s mode=%06o major=%d minor=%d", path, mode, major, minor); if ((descriptor = open(path, flags)) != -1) { logMessage(LOG_DEBUG, "device opened: %s: fd=%d", path, descriptor); } else { logMessage(LOG_DEBUG, "cannot open device: %s: %s", path, strerror(errno)); } } } } } } } if (descriptor != -1) { int ok = 0; struct stat status; if (fstat(descriptor, &status) == -1) { logMessage(LOG_DEBUG, "cannot fstat device: %d [%s]: %s", descriptor, path, strerror(errno)); } else if (!S_ISCHR(status.st_mode)) { logMessage(LOG_DEBUG, "not a character device: %s: fd=%d", path, descriptor); } else { ok = 1; } if (!ok) { close(descriptor); logMessage(LOG_DEBUG, "device closed: %s: fd=%d", path, descriptor); descriptor = -1; } } if (path) free(path); return descriptor; }
UsbSerial::UsbStatus UsbSerial::usbOpen( ) { QMutexLocker locker( &usbOpenMutex ); // Linux Only #if (defined(Q_WS_LINUX)) printf( "OSC over USB not implemented in Linux\n" ); return NOT_OPEN; #endif //Mac-only #ifdef Q_WS_MAC if( deviceOpen ) //if it's already open, do nothing. return ALREADY_OPEN; kern_return_t kernResult; io_iterator_t iterator = 0; kernResult = getDevicePath( iterator, deviceFilePath, sizeof(deviceFilePath) ); IOObjectRelease( iterator ); // clean up if (!deviceFilePath[0] ) { //printf("Didn't find a Make Controller.\n"); return NOT_OPEN; } // now try to actually do something deviceHandle = ::open( deviceFilePath, O_RDWR | O_NOCTTY | ( ( blocking ) ? 0 : O_NDELAY ) ); if ( deviceHandle < 0 ) { //printf( "Could not open the port (Error %d)\n", deviceHandle ); return NOT_OPEN; } else { deviceOpen = true; sleepMs( 10 ); //give it a moment after opening before trying to read/write // printf( "USB opened at %s\n", deviceFilePath ); messageInterface->message( 1, "Usb> Make Controller connected.\n" ); } return OK; #endif //Mac-only UsbSerial::open( ) //Windows-only #ifdef Q_WS_WIN if( deviceOpen ) //if it's already open, do nothing. return ALREADY_OPEN; TCHAR* openPorts[32]; int foundOpen = ScanEnumTree( TEXT("SYSTEM\\CURRENTCONTROLSET\\ENUM\\USB"), openPorts); //messageInterface->message( 1, "Found open: %d\n", foundOpen ); int i; for( i = 0; i < foundOpen; i++ ) { if( openPorts[i] != NULL ) { if( openDevice( openPorts[i] ) == 0 ) { messageInterface->message( 1, "Usb> Make Controller connected at %ls\n", openPorts[i] ); Sleep( 10 ); // wait after opening it before trying to read/write deviceOpen = true; // now set up to get called back when it's unplugged bool result; result = DoRegisterForNotification( &deviceNotificationHandle ); return OK; } //else //messageInterface->message( 1, "Found device but could not open: %ls\n", openPorts[i] ); } //else //messageInterface->message( 1, "Did not find any potential ports\n" ); } return NOT_OPEN; #endif //Windows-only UsbSerial::open( ) }
void SerialPortImpl::openImpl(const std::string& device, int baudRate, const std::string& parameters, FlowControlImpl flowControl) { if (device.empty()) { throw Poco::InvalidArgumentException("no device specified"); } const std::string devicePath = getDevicePath(device); #ifdef UNICODE std::wstring wdevicePath; Poco::UnicodeConverter::toUTF16(devicePath, wdevicePath); _handle = CreateFileW(wdevicePath.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); #else _handle = CreateFileA(devicePath.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); #endif if (_handle == INVALID_HANDLE_VALUE) { const DWORD lastError = GetLastError(); const std::string errorString = getErrorString(lastError); throw Poco::IOException(format("cannot open serial port %s:\n%s", device, errorString)); } DCB dcb = {0}; dcb.DCBlength = sizeof(dcb); if (!GetCommState(_handle, &dcb)) { const DWORD lastError = GetLastError(); const std::string errorString = getErrorString(lastError); throw Poco::IOException(format("cannot get serial port configuration for %s:\n%s", device, errorString)); } switch (parameters[0]) { case '5': dcb.ByteSize = 5; break; case '6': dcb.ByteSize = 6; break; case '7': dcb.ByteSize = 7; break; case '8': dcb.ByteSize = 8; break; default: throw Poco::InvalidArgumentException("invalid character size", parameters); } switch (parameters[1]) { case 'N': case 'n': dcb.Parity = NOPARITY; break; case 'E': case 'e': dcb.Parity = EVENPARITY; break; case 'o': case 'O': dcb.Parity = ODDPARITY; break; case 'm': case 'M': dcb.Parity = MARKPARITY; break; case 's': case 'S': dcb.Parity = SPACEPARITY; break; default: throw Poco::InvalidArgumentException("invalid parity setting", parameters); } switch (parameters[2]) { case '1': dcb.StopBits = ONESTOPBIT; break; case '2': dcb.StopBits = TWOSTOPBITS; break; case '5': dcb.StopBits = ONE5STOPBITS; break; default: throw Poco::InvalidArgumentException("invalid number of stop bits", parameters); } switch (flowControl) { case FLOW_NONE: dcb.fOutxCtsFlow = FALSE; dcb.fOutxDsrFlow = FALSE; dcb.fOutX = FALSE; dcb.fInX = FALSE; dcb.fRtsControl = RTS_CONTROL_DISABLE; break; case FLOW_RTSCTS: dcb.fOutxCtsFlow = TRUE; dcb.fOutxDsrFlow = TRUE; dcb.fOutX = FALSE; dcb.fInX = FALSE; dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; break; } DWORD speed = dcb.BaudRate; switch (baudRate) { case -1: break; case 110: speed = CBR_110; break; case 300: speed = CBR_300; break; case 600: speed = CBR_600; break; case 1200: speed = CBR_1200; break; case 2400: speed = CBR_2400; break; case 4800: speed = CBR_4800; break; case 9600: speed = CBR_9600; break; case 14400: speed = CBR_14400; break; case 19200: speed = CBR_19200; break; case 38400: speed = CBR_38400; break; case 57600: speed = CBR_57600; break; case 115200: speed = CBR_115200; break; case 128000: speed = CBR_128000; break; case 256000: speed = CBR_256000; break; default: // custom baudrate // We get ERROR_INVALID_PARAMETER from SetCommState if the settings is not supported. speed = baudRate; } dcb.BaudRate = speed; if (!SetCommState(_handle, &dcb)) { const DWORD lastError = GetLastError(); const std::string errorString = getErrorString(lastError); throw Poco::IOException(format("error setting serial port parameters on serial port %s:\n%s", device, errorString)); } COMMTIMEOUTS cto; cto.ReadIntervalTimeout = CHARACTER_TIMEOUT; cto.ReadTotalTimeoutConstant = MAXDWORD; cto.ReadTotalTimeoutMultiplier = 0; cto.WriteTotalTimeoutConstant = MAXDWORD; cto.WriteTotalTimeoutMultiplier = 0; if (!SetCommTimeouts(_handle, &cto)) { throw Poco::IOException("error setting serial port timeouts on serial port " + device); } }