Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
0
	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();
	}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 5
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;
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
0
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;
}
Ejemplo n.º 8
0
/*! \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
}
Ejemplo n.º 9
0
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;
}
Ejemplo n.º 10
0
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( )
}
Ejemplo n.º 11
0
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);
	}
}