char getUsbPortDetails()

in src/main/c/Posix/PosixHelperFunctions.c [1404:1502]


char getUsbPortDetails(const char* usbDeviceFile, char* portLocation, char* friendlyName, char** description, int* vendorID, int* productID, char* serialNumber, char* manufacturer, char* deviceDriver)
{
	// Only continue if this is a USB device
	char found = 0;
	sprintf(portLocation, "0-0");
	if (usbDeviceFile[0] != 'U')
		return found;

	// Attempt to locate the device in dmesg
	size_t bufferSize = 1024;
	strcpy(serialNumber, "Unknown");
	strcpy(manufacturer, "Unknown");
	strcpy(deviceDriver, "Unknown");
	char *stdOutResult = (char*)malloc(bufferSize), *device = (char*)malloc(64);
	snprintf(stdOutResult, bufferSize, "dmesg | grep ucom%s | tail -1", usbDeviceFile + 1);
	FILE *pipe = popen(stdOutResult, "r");
	device[0] = '\0';
	if (pipe)
	{
		while (fgets(stdOutResult, bufferSize, pipe))
			if (strstr(stdOutResult, " at "))
			{
				found = 1;
				sprintf(friendlyName, "ucom%s", usbDeviceFile + 1);
				strcpy(device, strstr(stdOutResult, " at ") + 4);
				device[strcspn(device, "\r\n")] = '\0';
			}
		pclose(pipe);
	}

	// Parse port location and description
	char *address = NULL, *port = NULL;
	if (device[0])
	{
		char* usbFile = (char*)malloc(64);
		for (int bus = 0; (bus < 255) && (!address || !port); ++bus)
		{
			// Ensure this bus exists
			struct stat fileStats;
			sprintf(usbFile, "/dev/usb%d", bus);
			if (stat(usbFile, &fileStats))
				continue;

			// Read the USB address and description
			snprintf(stdOutResult, bufferSize, "usbdevs -v -d /dev/usb%d 2>/dev/null | grep -B 2 %s", bus, device);
			pipe = popen(stdOutResult, "r");
			if (pipe)
			{
				while (fgets(stdOutResult, bufferSize, pipe))
				{
					if (strstr(stdOutResult, "addr ") && strrchr(stdOutResult, ','))
					{
						char *product = strrchr(stdOutResult, ',') + 2;
						product[strcspn(product, "\r\n")] = '\0';
						*description = (char*)realloc(*description, strlen(product) + 1);
						memcpy(*description, product, strlen(product) + 1);
					}
					if (strstr(stdOutResult, "addr "))
					{
						address = strstr(stdOutResult, "addr ") + 5;
						char *vid = strstr(stdOutResult, ": ") + 2;
						char *pid = strchr(vid, ':');
						*pid = '\0';
						*(strchr(pid+1, ' ')) = '\0';
						while (address[0] == '0')
							address = address + 1;
						*(strchr(address, ':')) = '\0';
						sprintf(portLocation, "%d-%s", bus, address);
						*vendorID = (int)strtol(vid, NULL, 16);
						*productID = (int)strtol(pid + 1, NULL, 16);
					}
				}
				pclose(pipe);
			}

			// Read the USB port location
			snprintf(stdOutResult, bufferSize, "dmesg | grep \"%s at \" | tail -1", device);
			pipe = popen(stdOutResult, "r");
			if (pipe)
			{
				while (fgets(stdOutResult, bufferSize, pipe))
					if (strstr(stdOutResult, "port "))
					{
						port = strstr(stdOutResult, "port ") + 5;
						*(strchr(port, ' ')) = '\0';
						strcat(portLocation, ".");
						strcat(portLocation, port);
					}
				pclose(pipe);
			}
		}
		free(usbFile);
	}

	// Clean up memory and return result
	free(device);
	free(stdOutResult);
	return found;
}