From mboxrd@z Thu Jan 1 00:00:00 1970 From: Antonio Ospite Date: Mon, 21 Feb 2011 22:45:02 +0000 Subject: Re: [RESEND] ID_SERIAL for udev bluetooth joystick events Message-Id: <20110221234502.c38a5205.ospite@studenti.unina.it> MIME-Version: 1 Content-Type: multipart/mixed; boundary="Signature=_Mon__21_Feb_2011_23_45_02_+0100_tgzlVZk=U=ew.fpx" List-Id: References: <20110210114204.9639661d.ospite@studenti.unina.it> In-Reply-To: <20110210114204.9639661d.ospite@studenti.unina.it> To: linux-hotplug@vger.kernel.org Cc: linux-input@vger.kernel.org, linux-bluetooth@vger.kernel.org --Signature=_Mon__21_Feb_2011_23_45_02_+0100_tgzlVZk=U=ew.fpx Content-Type: text/plain; charset=US-ASCII Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Thu, 10 Feb 2011 11:42:04 +0100 Antonio Ospite wrote: > Hi, >=20 > I have a question about udev events generated by a bluetooth joystick: > when udev generates the joystick event for a bt joystick, the ID_SERIAL > property matches the one of the bt adapter not the one of the joystick. > Ok, now I have a clearer picture of what udev does when I connect the joystick and I can pose better questions. > For example (using "udevadm monitor --property"), when connecting the > Sony Sixaxis via usb I get: > ID_SERIAL=3DSony_PLAYSTATION_R_3_Controller > in the input and joystick events, but when I connect it via bt, I get: > ID_SERIAL=3DBroadcom_Corp_ANYCOM_Blue_USB-200_250 > which matches my bluetooth adapter. >=20 This happens because /lib/udev/usb_id goes up to the usb device when creating the event for bt input devices connected to a btusb dongle. > Some insight of what I am trying to achieve with udev: > 1. Monitor new joystick devices. > 2. If ID_SERIAL !=3D Sony_PLAYSTATION_R_3_Controller, then STOP. > 3. Get the associated hidraw device node navigating the event tree. > 4. Set leds using the value from the ID_INPUT_JOYSTICK property. This is wrong, /lib/udev/input_id hardcodes a '1' as value there, I thought it was the index of the joystick like in: 1 -> js0 2 -> js1 but it is not, ID_INPUT_JOYSTICK=3D1 means just "this is a joystick", so I think I have to parse the DEVNAME (dev/jsX) to get the actual index, right? > 5. If ID_USB_DRIVER=3Dusbhid do the needed pairing. >=20 > And with the current behaviour for ID_SERIAL I cannot enforce 2. > I could listen for the (hid) event and use HID_NAME which seems to be a > little more consistent: > usb -> HID_NAME=3DSony PLAYSTATION(R)3 Controller > bt -> HID_NAME=3DPLAYSTATION(R)3 Controller > and navigate the event hierarchy to get ID_INPUT_JOYSTICK, but that is > slightly more complicated, and I am curious about the ID_SERIAL > behavior anyways :) > Maybe I'd still better monitor the 'input' event and move up and down from here to collect the joystick index and the hidraw device node, but I wonder if a patch along these lines (this is just for the sake of discussion) could have sense to prevent exposing the dongle properties also for the input devices: diff --git a/extras/usb_id/usb_id.c b/extras/usb_id/usb_id.c index fabd092..8e6e20f 100644 --- a/extras/usb_id/usb_id.c +++ b/extras/usb_id/usb_id.c @@ -56,6 +56,7 @@ static char serial_str[UTIL_NAME_SIZE]; static char packed_if_str[UTIL_NAME_SIZE]; static char revision_str[64]; static char type_str[64]; +static char bustype_str[64]; static char instance_str[64]; static const char *ifnum; static const char *driver; @@ -147,6 +148,29 @@ static int set_usb_mass_storage_ifsubtype(char *to, co= nst char *from, size_t len return type_num; } =20 +static int set_usb_input_bustype(char *to, const char *from, size_t len) +{ + int bustype_num =3D 0; + char *eptr; + char *type =3D "unknown"; + + bustype_num =3D strtoul(from, &eptr, 0); + if (eptr !=3D from) { + switch (bustype_num) { + case 3: + type =3D "usb"; + break; + case 5: + type =3D "bluetooth"; + break; + default: + break; + } + } + util_strscpy(to, len, type); + return bustype_num; +} + static void set_scsi_type(char *to, const char *from, size_t len) { int type_num; @@ -312,8 +336,8 @@ static int usb_id(struct udev_device *dev) set_usb_iftype(type_str, if_class_num, sizeof(type_str)-1); } =20 - info(udev, "%s: if_class %d protocol %d\n", - udev_device_get_syspath(dev_interface), if_class_num, protocol); + info(udev, "%s: if_class %d protocol %d type_str: %s\n", + udev_device_get_syspath(dev_interface), if_class_num, protocol, type= _str); =20 /* usb device directory */ dev_usb =3D udev_device_get_parent_with_subsystem_devtype(dev_interface, = "usb", "usb_device"); @@ -326,6 +350,57 @@ static int usb_id(struct udev_device *dev) /* all interfaces of the device in a single string */ dev_if_packed_info(dev_usb, packed_if_str, sizeof(packed_if_str)); =20 + /* input device XXX this check is not right, we might use a dev_input + * as below */ + if ((protocol =3D=3D 0) && !use_usb_info) { + struct udev_device *dev_input; + const char *input_vendor, *input_model, *input_rev, *input_bustype; + + /* get input device */ + dev_input =3D udev_device_get_parent_with_subsystem_devtype(dev, "input"= , NULL); + if (dev_input =3D=3D NULL) { + info(udev, "unable to find parent 'input' device of '%s'\n", + udev_device_get_syspath(dev)); + goto fallback; + } + + input_vendor =3D udev_device_get_sysattr_value(dev_input, "id/vendor"); + if (!input_vendor) { + info(udev, "%s: cannot get input vendor attribute\n", + udev_device_get_sysname(dev_input)); + goto fallback; + } + udev_util_encode_string(input_vendor, vendor_str_enc, sizeof(vendor_str_= enc)); + udev_util_replace_whitespace(input_vendor, vendor_str, sizeof(vendor_str= )-1); + udev_util_replace_chars(vendor_str, NULL); + + vendor_id =3D input_vendor; + product_id =3D udev_device_get_sysattr_value(dev_input, "id/product"); + + input_model =3D udev_device_get_sysattr_value(dev_input, "name"); + if (!input_model) { + info(udev, "%s: cannot get input model attribute\n", + udev_device_get_sysname(dev_input)); + goto fallback; + } + udev_util_encode_string(input_model, model_str_enc, sizeof(model_str_enc= )); + udev_util_replace_whitespace(input_model, model_str, sizeof(model_str)-1= ); + udev_util_replace_chars(model_str, NULL); + + input_rev =3D udev_device_get_sysattr_value(dev_input, "id/version"); + if (!input_rev) { + info(udev, "%s: cannot get input revision attribute\n", + udev_device_get_sysname(dev_input)); + goto fallback; + } + udev_util_replace_whitespace(input_rev, revision_str, sizeof(revision_st= r)-1); + udev_util_replace_chars(revision_str, NULL); + + /* get Bus type, see BUS_* in linux/input.h */ + input_bustype =3D udev_device_get_sysattr_value(dev_input, "id/bustype"); + set_usb_input_bustype(bustype_str, input_bustype, sizeof(bustype_str) - = 1 ); + } + /* mass storage : SCSI or ATAPI */ if ((protocol =3D=3D 6 || protocol =3D=3D 2) && !use_usb_info) { struct udev_device *dev_scsi; @@ -390,8 +465,12 @@ static int usb_id(struct udev_device *dev) } =20 fallback: - vendor_id =3D udev_device_get_sysattr_value(dev_usb, "idVendor"); - product_id =3D udev_device_get_sysattr_value(dev_usb, "idProduct"); + if (vendor_id[0] =3D=3D '\0') { + vendor_id =3D udev_device_get_sysattr_value(dev_usb, "idVendor"); + } + if (product_id[0] =3D=3D '\0') { + product_id =3D udev_device_get_sysattr_value(dev_usb, "idProduct"); + } =20 /* fallback to USB vendor & device */ if (vendor_str[0] =3D=3D '\0') { @@ -559,7 +638,7 @@ int main(int argc, char **argv) printf("ID_TYPE=3D%s\n", type_str); if (instance_str[0] !=3D '\0') printf("ID_INSTANCE=3D%s\n", instance_str); - printf("ID_BUS=3Dusb\n"); + printf("ID_BUS=3D%s\n", (bustype_str[0] =3D=3D '\0') ? "usb" : bustype_= str); if (packed_if_str[0] !=3D '\0') printf("ID_USB_INTERFACES=3D:%s\n", packed_if_str); if (ifnum !=3D NULL) Thanks, Antonio --=20 Antonio Ospite http://ao2.it PGP public key ID: 0x4553B001 A: Because it messes up the order in which people normally read text. See http://en.wikipedia.org/wiki/Posting_style Q: Why is top-posting such a bad thing? --Signature=_Mon__21_Feb_2011_23_45_02_+0100_tgzlVZk=U=ew.fpx Content-Type: application/pgp-signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iEYEARECAAYFAk1i6u4ACgkQ5xr2akVTsAFlRwCbB2RpOPrrAOqqpnApnhUmzCnD pU8An0izx3VxJwMfRSe7h7fBhUlQh/Jq =tV33 -----END PGP SIGNATURE----- --Signature=_Mon__21_Feb_2011_23_45_02_+0100_tgzlVZk=U=ew.fpx--