From 4da37c1e130e32c4bbad13de7461e0612ca15597 Mon Sep 17 00:00:00 2001
From: Martin Szulecki
Date: Mon, 10 Nov 2014 16:58:10 +0100
Subject: Get USB speed for device and use it for device attached client
 message

---
 src/client.c    |  3 +--
 src/device.c    |  2 ++
 src/device.h    |  1 +
 src/usb-linux.c | 29 +++++++++++++++++++++++++++++
 src/usb.h       |  1 +
 5 files changed, 34 insertions(+), 2 deletions(-)

(limited to 'src')

diff --git a/src/client.c b/src/client.c
index 403340a..268c8b9 100644
--- a/src/client.c
+++ b/src/client.c
@@ -306,8 +306,7 @@ static plist_t create_device_attached_plist(struct device_info *dev)
 	plist_dict_set_item(dict, "MessageType", plist_new_string("Attached"));
 	plist_dict_set_item(dict, "DeviceID", plist_new_uint(dev->id));
 	plist_t props = plist_new_dict();
-	// TODO: get current usb speed
-	plist_dict_set_item(props, "ConnectionSpeed", plist_new_uint(480000000));
+	plist_dict_set_item(props, "ConnectionSpeed", plist_new_uint(dev->speed));
 	plist_dict_set_item(props, "ConnectionType", plist_new_string("USB"));
 	plist_dict_set_item(props, "DeviceID", plist_new_uint(dev->id));
 	plist_dict_set_item(props, "LocationID", plist_new_uint(dev->location));
diff --git a/src/device.c b/src/device.c
index e5377cc..ddd1d4a 100644
--- a/src/device.c
+++ b/src/device.c
@@ -572,6 +572,7 @@ static void device_version_input(struct mux_device *dev, struct version_header *
 	info.location = usb_get_location(dev->usbdev);
 	info.serial = usb_get_serial(dev->usbdev);
 	info.pid = usb_get_pid(dev->usbdev);
+	info.speed = usb_get_speed(dev->usbdev);
 	preflight_worker_device_add(&info);
 }
 
@@ -924,6 +925,7 @@ int device_get_list(int include_hidden, struct device_info **devices)
 			p->serial = usb_get_serial(dev->usbdev);
 			p->location = usb_get_location(dev->usbdev);
 			p->pid = usb_get_pid(dev->usbdev);
+			p->speed = usb_get_speed(dev->usbdev);
 			count++;
 			p++;
 		}
diff --git a/src/device.h b/src/device.h
index e731b36..85703e4 100644
--- a/src/device.h
+++ b/src/device.h
@@ -28,6 +28,7 @@ struct device_info {
 	const char *serial;
 	uint32_t location;
 	uint16_t pid;
+	uint64_t speed;
 };
 
 void device_data_input(struct usb_device *dev, unsigned char *buf, uint32_t length);
diff --git a/src/usb-linux.c b/src/usb-linux.c
index 8acbace..9878f41 100644
--- a/src/usb-linux.c
+++ b/src/usb-linux.c
@@ -56,6 +56,7 @@ struct usb_device {
 	struct collection rx_xfers;
 	struct collection tx_xfers;
 	int wMaxPacketSize;
+	uint64_t speed;
 };
 
 static struct collection device_list;
@@ -425,6 +426,7 @@ int usb_discover(void)
 		usbdev->address = address;
 		usbdev->vid = devdesc.idVendor;
 		usbdev->pid = devdesc.idProduct;
+		usbdev->speed = 480000000;
 		usbdev->dev = handle;
 		usbdev->alive = 1;
 		usbdev->wMaxPacketSize = libusb_get_max_packet_size(dev, usbdev->ep_out);
@@ -435,6 +437,25 @@ int usb_discover(void)
 			usbmuxd_log(LL_INFO, "Using wMaxPacketSize=%d for device %d-%d", usbdev->wMaxPacketSize, usbdev->bus, usbdev->address);
 		}
 
+		switch (libusb_get_device_speed(dev)) {
+			case LIBUSB_SPEED_LOW:
+				usbdev->speed = 1500000;
+				break;
+			case LIBUSB_SPEED_FULL:
+				usbdev->speed = 12000000;
+				break;
+			case LIBUSB_SPEED_SUPER:
+				usbdev->speed = 5000000000;
+				break;
+			case LIBUSB_SPEED_HIGH:
+			case LIBUSB_SPEED_UNKNOWN:
+			default:
+				usbdev->speed = 480000000;
+				break;
+		}
+
+		usbmuxd_log(LL_INFO, "USB Speed is %g MBit/s for device %d-%d", (double)(usbdev->speed / 1000000.0), usbdev->bus, usbdev->address);
+
 		collection_init(&usbdev->tx_xfers);
 		collection_init(&usbdev->rx_xfers);
 
@@ -510,6 +531,14 @@ uint16_t usb_get_pid(struct usb_device *dev)
 	return dev->pid;
 }
 
+uint64_t usb_get_speed(struct usb_device *dev)
+{
+	if (!dev->dev) {
+		return 0;
+	}
+	return dev->speed;
+}
+
 void usb_get_fds(struct fdlist *list)
 {
 	const struct libusb_pollfd **usbfds;
diff --git a/src/usb.h b/src/usb.h
index 8eff456..da784b3 100644
--- a/src/usb.h
+++ b/src/usb.h
@@ -54,6 +54,7 @@ void usb_shutdown(void);
 const char *usb_get_serial(struct usb_device *dev);
 uint32_t usb_get_location(struct usb_device *dev);
 uint16_t usb_get_pid(struct usb_device *dev);
+uint64_t usb_get_speed(struct usb_device *dev);
 void usb_get_fds(struct fdlist *list);
 int usb_get_timeout(void);
 int usb_send(struct usb_device *dev, const unsigned char *buf, int length);
-- 
cgit v1.1-32-gdbae