Skip to content

Commit

Permalink
Generate device ID as needed (Issue #234)
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelrsweet committed Nov 10, 2022
1 parent e313253 commit 1a28cf9
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 30 deletions.
2 changes: 2 additions & 0 deletions CHANGES.md
Expand Up @@ -19,6 +19,8 @@ Changes in v1.3.0
configure option.
- Added Turkish and Norwegian Bokmål localizations.
- Changed names of PAPPL-specific attributes to use "smi55357" prefix.
- Updated USB device code to generate a 1284 device ID and use the manufacturer
and product strings when necessary (Issue #234)
- Fixed a device race condition with job processing.
- Fixed a initialization timing issue with USB gadgets on newer Linux kernels.
- Fixed a potential memory underflow with USB device IDs.
Expand Down
98 changes: 68 additions & 30 deletions pappl/device-usb.c
@@ -1,7 +1,7 @@
//
// USB device support code for the Printer Application Framework
//
// Copyright © 2019-2021 by Michael R Sweet.
// Copyright © 2019-2022 by Michael R Sweet.
// Copyright © 2007-2019 by Apple Inc.
//
// Licensed under Apache License v2.0. See the file "LICENSE" for more
Expand All @@ -20,6 +20,13 @@
#endif // HAVE_LIBUSB


//
// Local constants...
//

#define _PAPPL_MAX_DEVICE_ID 1024 // Maximum length of device ID string


//
// Local types...
//
Expand All @@ -37,6 +44,8 @@ typedef struct _pappl_usb_dev_s // USB device data
write_endp, // Write endpoint
read_endp, // Read endpoint
protocol; // Protocol: 1 = Uni-di, 2 = Bi-di.
char device_id[_PAPPL_MAX_DEVICE_ID];
// IEEE-1284 device ID
} _pappl_usb_dev_t;
#endif // HAVE_LIBUSB

Expand Down Expand Up @@ -131,7 +140,8 @@ pappl_usb_find(
for (i = 0; i < num_udevs; i ++)
{
libusb_device *udevice = udevs[i]; // Current device
char device_id[1024], // Current device ID
char device_id_buf[_PAPPL_MAX_DEVICE_ID + 2],
// Current device ID buffer
device_info[256], // Current device description
device_uri[1024]; // Current device URI
struct libusb_device_descriptor devdesc;
Expand Down Expand Up @@ -330,30 +340,30 @@ pappl_usb_find(
if (device->handle)
{
// Get the 1284 Device ID...
if ((err = libusb_control_transfer(device->handle, LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_ENDPOINT_IN | LIBUSB_RECIPIENT_INTERFACE, 0, (uint16_t)device->conf, (uint16_t)((device->iface << 8) | device->altset), (unsigned char *)device_id, sizeof(device_id), 5000)) < 0)
if ((err = libusb_control_transfer(device->handle, LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_ENDPOINT_IN | LIBUSB_RECIPIENT_INTERFACE, 0, (uint16_t)device->conf, (uint16_t)((device->iface << 8) | device->altset), (unsigned char *)device_id_buf, sizeof(device_id_buf), 5000)) < 0)
{
_papplDeviceError(err_cb, err_data, "Unable to get IEEE-1284 device ID: %s", libusb_strerror((enum libusb_error)err));
device_id[0] = '\0';
device_id_buf[0] = '\0';
libusb_close(device->handle);
device->handle = NULL;
}
else
{
int length = ((device_id[0] & 255) << 8) | (device_id[1] & 255);
int length = ((device_id_buf[0] & 255) << 8) | (device_id_buf[1] & 255);

if (length < 14 || length > (int)sizeof(device_id))
length = ((device_id[1] & 255) << 8) | (device_id[0] & 255);
if (length < 14 || length > (int)sizeof(device->device_id))
length = ((device_id_buf[1] & 255) << 8) | (device_id_buf[0] & 255);

if (length > (int)(sizeof(device_id) - 2))
length = (int)(sizeof(device_id) - 2);
if (length > (int)(sizeof(device->device_id)))
length = (int)(sizeof(device->device_id));
else if (length < 2)
length = 0;
else
length -= 2;

if (length > 0)
memmove(device_id, device_id + 2, (size_t)length);
device_id[length] = '\0';
memmove(device->device_id, device_id_buf + 2, (size_t)length);
device->device_id[length] = '\0';

_PAPPL_DEBUG("pappl_usb_find: device_id=\"%s\"\n", device_id);
}
Expand All @@ -366,58 +376,76 @@ pappl_usb_find(
*model, // Pointer to model
*serial = NULL; // Pointer to serial number
char *ptr, // Pointer into device ID
copy_did[1024], // Copy of device ID
temp[256]; // Temporary string for serial #
copy_did[_PAPPL_MAX_DEVICE_ID],
// Copy of device ID
temp_mfg[256], // Temporary string for manufacturer
temp_mdl[256], // Temporary string for model
temp_sn[256]; // Temporary string for serial #
int length; // Length of string

if ((length = libusb_get_string_descriptor_ascii(device->handle, devdesc.iManufacturer, (unsigned char *)temp_mfg, sizeof(temp_mfg) - 1)) > 0)
temp_mfg[length] = '\0';
else
papplCopyString(temp_mfg, "Unknown", sizeof(temp_mfg));

if ((length = libusb_get_string_descriptor_ascii(device->handle, devdesc.iProduct, (unsigned char *)temp_mdl, sizeof(temp_mdl) - 1)) > 0)
temp_mdl[length] = '\0';
else
papplCopyString(temp_mdl, "Product", sizeof(temp_mdl));

papplCopyString(copy_did, device_id, sizeof(copy_did));
if ((length = libusb_get_string_descriptor_ascii(device->handle, devdesc.iSerialNumber, (unsigned char *)temp_sn, sizeof(temp_sn) - 1)) > 0)
temp_sn[length] = '\0';
else
snprintf(temp_sn, sizeof(temp_sn), "%d.%d", device->conf, device->iface);

if (!device->device_id[0])
{
// Blank device ID, build one from the USB device strings...
snprintf(device->device_id, sizeof(device->device_id), "MFG:%s;MDL:%s;SN:%s;", temp_mfg, temp_mdl, temp_sn);
}

papplCopyString(copy_did, device->device_id, sizeof(copy_did));

if ((make = strstr(copy_did, "MANUFACTURER:")) != NULL)
make += 13;
else if ((make = strstr(copy_did, "MFG:")) != NULL)
make += 4;
else
make = temp_mfg;

if ((model = strstr(copy_did, "MODEL:")) != NULL)
model += 6;
else if ((model = strstr(copy_did, "MDL:")) != NULL)
model += 4;
else
model = temp_mdl;

if ((serial = strstr(copy_did, "SERIALNUMBER:")) != NULL)
serial += 12;
else if ((serial = strstr(copy_did, "SERN:")) != NULL)
serial += 5;
else if ((serial = strstr(copy_did, "SN:")) != NULL)
serial += 3;
else
serial = temp_sn;

if (serial)
{
if ((ptr = strchr(serial, ';')) != NULL)
*ptr = '\0';
}
else
{
int length = libusb_get_string_descriptor_ascii(device->handle, devdesc.iSerialNumber, (unsigned char *)temp, sizeof(temp) - 1);
if (length > 0)
{
temp[length] = '\0';
serial = temp;
}
}

if (make)
{
if ((ptr = strchr(make, ';')) != NULL)
*ptr = '\0';
}
else
make = "Unknown";

if (model)
{
if ((ptr = strchr(model, ';')) != NULL)
*ptr = '\0';
}
else
model = "Unknown";

if (serial)
httpAssembleURIf(HTTP_URI_CODING_ALL, device_uri, sizeof(device_uri), "usb", NULL, make, 0, "/%s?serial=%s", model, serial);
Expand All @@ -429,7 +457,7 @@ pappl_usb_find(
else
snprintf(device_info, sizeof(device_info), "%s %s (USB)", make, model);

if ((*cb)(device_info, device_uri, device_id, data))
if ((*cb)(device_info, device_uri, device->device_id, data))
{
_PAPPL_DEBUG("pappl_usb_find: Found a match.\n");

Expand Down Expand Up @@ -502,8 +530,18 @@ pappl_usb_getid(
length = bufsize;

length -= 2;
memmove(buffer, buffer + 2, length);
buffer[length] = '\0';

if (length > 0)
{
// Copy live value...
memmove(buffer, buffer + 2, length);
buffer[length] = '\0';
}
else
{
// Use cached value...
papplCopyString(buffer, usb->device_id, bufsize);
}

return (buffer);
}
Expand Down

0 comments on commit 1a28cf9

Please sign in to comment.