From 86fa94fdc73414ae1efb1bbac836a065d141690a Mon Sep 17 00:00:00 2001
From: Martino Facchin <m.facchin@arduino.cc>
Date: Wed, 21 Oct 2015 16:45:55 +0200
Subject: [PATCH] PUSB: add iSerial USB field

---
 cores/arduino/USB/PluggableUSB.cpp |  9 +++++++++
 cores/arduino/USB/PluggableUSB.h   |  2 ++
 cores/arduino/USB/USBCore.cpp      | 11 +++++++++--
 cores/arduino/USB/USBDesc.h        |  5 ++++-
 libraries/HID/HID.cpp              | 10 ++++++++++
 libraries/HID/HID.h                |  1 +
 6 files changed, 35 insertions(+), 3 deletions(-)

diff --git a/cores/arduino/USB/PluggableUSB.cpp b/cores/arduino/USB/PluggableUSB.cpp
index 0f2d08c0..4c52c1fa 100644
--- a/cores/arduino/USB/PluggableUSB.cpp
+++ b/cores/arduino/USB/PluggableUSB.cpp
@@ -52,6 +52,15 @@ int PluggableUSB_::getDescriptor(USBSetup& setup)
 	return 0;
 }
 
+void PluggableUSB_::getShortName(char *iSerialNum)
+{
+       PluggableUSBModule* node;
+       for (node = rootNode; node; node = node->next) {
+               iSerialNum += node->getShortName(iSerialNum);
+       }
+       *iSerialNum = 0;
+}
+
 bool PluggableUSB_::setup(USBSetup& setup)
 {
 	PluggableUSBModule* node;
diff --git a/cores/arduino/USB/PluggableUSB.h b/cores/arduino/USB/PluggableUSB.h
index eb18ca25..4e08e5df 100644
--- a/cores/arduino/USB/PluggableUSB.h
+++ b/cores/arduino/USB/PluggableUSB.h
@@ -35,6 +35,7 @@ protected:
   virtual bool setup(USBSetup& setup) = 0;
   virtual int getInterface(uint8_t* interfaceCount) = 0;
   virtual int getDescriptor(USBSetup& setup) = 0;
+  virtual uint8_t getShortName(char *name) { name[0] = 'A'+pluggedInterface; return 1; }
 
   uint8_t pluggedInterface;
   uint8_t pluggedEndpoint;
@@ -55,6 +56,7 @@ public:
   int getInterface(uint8_t* interfaceCount);
   int getDescriptor(USBSetup& setup);
   bool setup(USBSetup& setup);
+  void getShortName(char *iSerialNum);
 
 private:
   uint8_t lastIf;
diff --git a/cores/arduino/USB/USBCore.cpp b/cores/arduino/USB/USBCore.cpp
index a584a638..9642c2aa 100644
--- a/cores/arduino/USB/USBCore.cpp
+++ b/cores/arduino/USB/USBCore.cpp
@@ -66,8 +66,8 @@ const uint8_t STRING_MANUFACTURER[] = USB_MANUFACTURER;
 
 
 //	DEVICE DESCRIPTOR
-const DeviceDescriptor USB_DeviceDescriptorB = D_DEVICE(0xEF, 0x02, 0x01, 64, USB_VID, USB_PID, 0x100, IMANUFACTURER, IPRODUCT, 0, 1);
-const DeviceDescriptor USB_DeviceDescriptor = D_DEVICE(0x00, 0x00, 0x00, 64, USB_VID, USB_PID, 0x100, IMANUFACTURER, IPRODUCT, 0, 1);
+const DeviceDescriptor USB_DeviceDescriptorB = D_DEVICE(0xEF, 0x02, 0x01, 64, USB_VID, USB_PID, 0x100, IMANUFACTURER, IPRODUCT, ISERIAL, 1);
+const DeviceDescriptor USB_DeviceDescriptor = D_DEVICE(0x00, 0x00, 0x00, 64, USB_VID, USB_PID, 0x100, IMANUFACTURER, IPRODUCT, ISERIAL, 1);
 
 //==================================================================
 
@@ -208,6 +208,13 @@ bool USBDeviceClass::sendDescriptor(USBSetup &setup)
 		else if (setup.wValueL == IMANUFACTURER) {
 			return sendStringDescriptor(STRING_MANUFACTURER, setup.wLength);
 		}
+		else if (setup.wValueL == ISERIAL) {
+#ifdef PLUGGABLE_USB_ENABLED
+			char name[ISERIAL_MAX_LEN];
+			PluggableUSB().getShortName(name);
+			return sendStringDescriptor((uint8_t*)name, setup.wLength);
+#endif
+		}
 		else {
 			return false;
 		}
diff --git a/cores/arduino/USB/USBDesc.h b/cores/arduino/USB/USBDesc.h
index 2282a718..e4335aa9 100644
--- a/cores/arduino/USB/USBDesc.h
+++ b/cores/arduino/USB/USBDesc.h
@@ -41,8 +41,11 @@
 #define CDC_TX CDC_ENDPOINT_IN
 #endif
 
+#define ISERIAL_MAX_LEN        20
+
 // Defined string description
 #define IMANUFACTURER	1
-#define IPRODUCT		2
+#define IPRODUCT    2
+#define ISERIAL    3
 
 #endif /* __USBDESC_H__ */
diff --git a/libraries/HID/HID.cpp b/libraries/HID/HID.cpp
index 94bf9f59..34995fe6 100644
--- a/libraries/HID/HID.cpp
+++ b/libraries/HID/HID.cpp
@@ -60,6 +60,16 @@ int HID_::getDescriptor(USBSetup& setup)
 	return total;
 }
 
+uint8_t HID_::getShortName(char *name)
+{
+       name[0] = 'H';
+       name[1] = 'I';
+       name[2] = 'D';
+       name[3] = 'A' + (descriptorSize & 0x0F);
+       name[4] = 'A' + ((descriptorSize >> 4) & 0x0F);
+       return 5;
+}
+
 void HID_::AppendDescriptor(HIDSubDescriptor *node)
 {
 	if (!rootNode) {
diff --git a/libraries/HID/HID.h b/libraries/HID/HID.h
index e5dfa339..9499b726 100644
--- a/libraries/HID/HID.h
+++ b/libraries/HID/HID.h
@@ -96,6 +96,7 @@ protected:
   int getInterface(uint8_t* interfaceCount);
   int getDescriptor(USBSetup& setup);
   bool setup(USBSetup& setup);
+  uint8_t getShortName(char* name);
 
 private:
   uint32_t epType[1];
-- 
GitLab