Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

279
Vistas
Linux: intento de obtener ID de producto y proveedor de joystick a través de ioctl, obtenga EINVAL en su lugar

Estoy tratando de leer el nombre, la identificación del proveedor y la identificación del producto para un joystick USB en Ubuntu (específicamente, estoy trabajando con una almohadilla Xbox 360 con cable en Ubuntu 13.10 x64). Puedo leer el nombre, pero cuando intento leer las identificaciones del proveedor y del producto, aparece un error EINVAL . El código es el siguiente:

 if (plugged[index]) { char name[32]; std::snprintf(name, sizeof(name), "/dev/input/js%u", index); // Open the joystick's file descriptor (read-only and non-blocking) m_file = ::open(name, O_RDONLY | O_NONBLOCK); if (m_file >= 0) { // Retrieve the axes mapping ioctl(m_file, JSIOCGAXMAP, m_mapping); // Get the name char joyname[128]; if (ioctl(m_file, JSIOCGNAME(128), joyname) < 0) { m_name = "Unknown Joystick"; } else { m_name = joyname; } // Get vendor and product IDs input_id inpid; if (ioctl(m_file, EVIOCGID, &inpid) < 0) { if (errno == EBADF) printf("EBADF\n"); if (errno == EFAULT) printf("EFAULT\n"); if (errno == ENOTTY) printf("ENOTTY\n"); if (errno == EINVAL) printf("EINVAL\n"); m_manufacturerID = 0; m_productID = 0; } else { m_manufacturerID = inpid.vendor; m_productID = inpid.product; } // Reset the joystick state m_state = JoystickState(); return true; } else { return false; } } else { return false; }

El fragmento que lee los ID de proveedores y productos es:

 ioctl(m_file, EVIOCGID, &inpid)

De acuerdo con la página del manual para ioctl , EINVAL , la solicitud ( EVIOCGID ) o argp ( inpid ) no es válida.

¿Cómo puedo determinar cuál no es válido?

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

Después de investigar un poco más, descubrí que la razón por la que ioctl(m_file, EVIOCGID, &inpid) es que el dispositivo que abro es un joystick ( /dev/input/js ) y EVIOCGID ioctl es para dispositivos de eventos ( /dev/input/event ) por lo tanto, la falla. Desafortunadamente, no hay JSIOCGID ioctl, así que tuve que cambiar de táctica. En su lugar, estoy usando udev para acceder a los identificadores de productos y proveedores del joystick. Aquí está el código que estoy usando:

 // Use udev to look up the product and manufacturer IDs struct udev *udev = udev_new(); if (udev) { char sysname[32]; std::snprintf(sysname, sizeof(sysname), "js%u", index); struct udev_device *dev = udev_device_new_from_subsystem_sysname(udev, "input", sysname); dev = udev_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_device"); if (!dev) { err() << "Unable to find parent USB device" << std::endl; } std::stringstream ss; ss << std::hex << udev_device_get_sysattr_value(dev, "idVendor"); ss >> m_manufacturerID; ss.clear(); ss.str(""); ss << std::hex << udev_device_get_sysattr_value(dev, "idProduct"); ss >> m_productID; udev_device_unref(dev); udev_unref(udev); } else { err() << "Cannot create udev" << std::endl; }

Con udev, he podido recuperar de manera consistente las ID de proveedores y productos para joysticks USB en Ubuntu 13.10 x64.

ACTUALIZAR

He probado esto más con:

  • Linux Mint 16 x64
  • Manjaro x64
  • Fedora 20x64

En todos los casos, este código funcionó muy bien.

over 4 years ago · Santiago Trujillo Denunciar

0

Solo un ejemplo un poco más limpio con corrección de errores menores:

 #include <iostream> #include <libudev.h> #include <sstream> bool getJoystickInfo(int index, std::string& manufacturerID, std::string& productID, std::string& message) { // Use udev to look up the product and manufacturer IDs struct udev *udev = udev_new(); if (udev) { char sysname[32]; std::snprintf(sysname, sizeof(sysname), "js%u", index); struct udev_device *dev = udev_device_new_from_subsystem_sysname(udev, "input", sysname); dev = udev_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_device"); if (!dev) { message = "Unable to find parent USB device"; return false; } std::stringstream ss; ss << std::hex << udev_device_get_sysattr_value(dev, "idVendor"); ss >> manufacturerID; ss.clear(); ss.str(""); ss << std::hex << udev_device_get_sysattr_value(dev, "idProduct"); ss >> productID; udev_device_unref(dev); } else { message = "Cannot create udev"; return false; } udev_unref(udev); return true; } int main() { std::string manufacturerID, productID, message; if (getJoystickInfo(1, manufacturerID, productID, message)) std::cout << manufacturerID << "\t" << productID << std::endl; else std::cerr << message << std::endl; return 0; }

Para compilarlo, pase la opción -ludev a gcc o use lo siguiente en CMakeLists.txt:

 target_link_libraries(MyExecutable udev)
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda