Fixed that SDB doese not detect tizen device on OSX 10.11
authorshingil.kang <shingil.kang@samsung.com>
Tue, 20 Oct 2015 09:05:01 +0000 (18:05 +0900)
committershingil.kang <shingil.kang@samsung.com>
Wed, 21 Oct 2015 07:25:01 +0000 (16:25 +0900)
- SDB communicate with tizen target by SDB protocol.
  Configuration #2 of device has SDB protocal.
  On OSX 10.11, default configuration is set to #1.
  So SDB  set configuration to #2 to use SDB protocal.

Change-Id: Ie4f5919f6bf902825ab782b0ef59b6aab2b2295a
Signed-off-by: shingil.kang <shingil.kang@samsung.com>
src/sdb_usb.h
src/usb_darwin.c

index 23cf6feb7ab406e11e1b274c769bc0600358311c..744a357bc667d7b5ddde5f180873f0fc2021b90d 100755 (executable)
@@ -28,9 +28,13 @@ void    kick_disconnected_devices();
 #define ADB_INTERFACE_SUBCLASS           0x42
 #define SDB_INTERFACE_PROTOCOL           0x02
 #define ADB_INTERFACE_PROTOCOL           0x01
+
 // Samsung's USB Vendor ID
 #define VENDOR_ID_SAMSUNG                0x04e8
 
+// Tizen product ID
+#define PRODUCT_ID_TIZEN                 0x6860
+
 /*
  * Linux usbfs has a limit of one page size for synchronous bulk read/write.
  * 4096 is the most portable maximum we can do for now.
index 61a37cec4ad7787e021cebeca905df4b8ad0ec23..c2c2835b8cc76596230ad3a49c3484217feb7ec7 100755 (executable)
@@ -249,13 +249,21 @@ void DeviceAdded(void *refCon, io_iterator_t iterator) {
     UInt16 usbProduct;
     UInt8 serialIndex;
     char serial[256];
+    IOReturn ior;
+    int count = 0;
+
+    LOG_DEBUG("enum usb interface\n");
 
     while ((usbInterface = IOIteratorNext(iterator))) {
+
+        LOG_DEBUG("usb(%d) interface\n", count++);
+
         // Create an intermediate plug-in
         kr = IOCreatePlugInInterfaceForService(usbInterface, kIOUSBInterfaceUserClientTypeID,
                 kIOCFPlugInInterfaceID, &ioDev, &score);
         IOObjectRelease(usbInterface);
 
+
         if ((kIOReturnSuccess != kr) || !ioDev) {
             LOG_DEBUG("couldn't create a device interface plugin, find next...\n");
             continue;
@@ -264,6 +272,7 @@ void DeviceAdded(void *refCon, io_iterator_t iterator) {
                 CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID), (LPVOID) & interface);
         (*ioDev)->Release(ioDev);
 
+
         if (res || !interface) {
             LOG_DEBUG("couldn't create an IOUSBInterfaceInterface, find next... \n");
             continue;
@@ -295,20 +304,69 @@ void DeviceAdded(void *refCon, io_iterator_t iterator) {
             LOG_DEBUG("couldn't create a usb interface, find next...\n");
             continue;
         }
+
         // Get vendor, product and serial index
         kr = (*intf)->GetDeviceVendor(intf, &usbVendor);
         if (kIOReturnSuccess != kr) {
             LOG_ERROR("couldn't get usb vendor name\n");
         }
+
         kr = (*intf)->GetDeviceProduct(intf, &usbProduct);
         if (kIOReturnSuccess != kr) {
             LOG_ERROR("couldn't get usb product name\n");
         }
+
         kr = (*intf)->USBGetSerialNumberStringIndex(intf, &serialIndex);
         if (kIOReturnSuccess != kr) {
             LOG_ERROR("couldn't get usb serial index\n");
         }
+
         kr = getUSBSerial(intf, serialIndex, serial);
+
+        LOG_DEBUG("usbVendor=%x usbProduct=%x\n", usbVendor, usbProduct);
+
+        // get total configuration number
+        // Tizen target has sdb interface with configuration descriptor #2
+        UInt8 totalConfigNum;
+        (*intf)->GetNumberOfConfigurations(intf, &totalConfigNum);
+        LOG_DEBUG("total configuration number: %d\n", totalConfigNum);
+
+        // get current set configuration
+        UInt8 configNum;
+        ior = (*intf)->GetConfiguration(intf, &configNum);
+        if (ior)
+        {
+             LOG_ERROR("failed to get current configuration\n");
+             continue;
+        }
+        LOG_DEBUG("get current set configuration: %d\n", configNum);
+
+        // OS X with 10.11, configuration of tizen device is set to #1. so must change configuration to #2.
+        if((usbProduct == PRODUCT_ID_TIZEN) && (totalConfigNum == 2) && (configNum != 2)) {
+            // Open the device to change its state
+            ior = (*intf)->USBDeviceOpen(intf);
+            if (ior != kIOReturnSuccess)
+            {
+                LOG_ERROR("Unable to open device: %08x\n", ior);
+                (void) (*intf)->Release(intf);
+                continue;
+            } else {
+                UInt8 sdb_configuration = 2;
+
+                // Set configuration to 2
+                ior = (*intf)->SetConfiguration(intf, sdb_configuration);
+                if (ior)
+                {
+                    LOG_ERROR("failed to set configuration to 2 (err = %08x)\n", ior);
+                    (void) (*intf)->USBDeviceClose(intf);
+                    (void) (*intf)->Release(intf);
+                    continue;
+                } else  {
+                    LOG_DEBUG("set configuration to 2\n");
+                    (void) (*intf)->USBDeviceClose(intf);
+                }
+            }
+        }
         (*intf)->Release(intf);
 
         usb_handle* handle = calloc(1, sizeof(usb_handle));
@@ -415,66 +473,49 @@ void do_lsusb(void) {
     gRunLoop = CFRunLoopGetCurrent();
     CFRunLoopAddSource(gRunLoop, runLoopSource, kCFRunLoopDefaultMode);
 
-    for (i = 0; tizen_device_vendors[i].vendor != NULL; i++) {
-        // Set up the matching criteria for the devices we're interested in.  The matching criteria needs to follow
-        // the same rules as kernel drivers:  mainly it needs to follow the USB Common Class Specification, pp. 6-7.
-        // See also http://developer.apple.com/qa/qa2001/qa1076.html
-        // One exception is that you can use the matching dictionary "as is", i.e. without adding any matching criteria
-        // to it and it will match every IOUSBDevice in the system.  IOServiceAddMatchingNotification will consume this
-        // dictionary reference, so there is no need to release it later on.
-        //
-        matchingDict = IOServiceMatching(kIOUSBInterfaceClassName); // Interested in instances of class
-                                                                    // IOUSBInterface and its subclasses
-        if (!matchingDict) {
-            LOG_DEBUG("Can't create a USB matching dictionary\n");
-            mach_port_deallocate(mach_task_self(), masterPort);
-            return;
-        }
-        usbVendor = tizen_device_vendors[i].id;
-        subClass = tizen_device_vendors[i].subclass;
-        protocol = tizen_device_vendors[i].protocol;
-
-        LOG_DEBUG("Looking for devices matching vendor ID=%0x(%0x, %0x)\n", usbVendor, subClass, protocol);
-
-        // We are interested in all USB Devices (as opposed to USB interfaces).  The Common Class Specification
-        // tells us that we need to specify the idVendor, idProduct, and bcdDevice fields, or, if we're not interested
-        // in particular bcdDevices, just the idVendor and idProduct.  Note that if we were trying to match an IOUSBInterface,
-        // we would need to set more values in the matching dictionary (e.g. idVendor, idProduct, bInterfaceNumber and
-        // bConfigurationValue.
-        //
-
-        // Create a CFNumber for the idVendor, interface subclass and protocol and set the value in the dictionary
-        //
-        numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &usbVendor);
-        CFDictionarySetValue(matchingDict, CFSTR(kUSBVendorID), numberRef);
-        CFRelease(numberRef);
-
-        numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &subClass);
-        CFDictionarySetValue(matchingDict, CFSTR(kUSBInterfaceSubClass), numberRef);
-        CFRelease(numberRef);
-
-        numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &protocol);
-        CFDictionarySetValue(matchingDict, CFSTR(kUSBInterfaceProtocol), numberRef);
-        CFRelease(numberRef);
-
-        numberRef = 0;
-
-        // Now set up a notification to be called when a device is first matched by I/O Kit.
-        // Note that this will not catch any devices that were already plugged in so we take
-        // care of those later.
-        //
-        kr = IOServiceAddMatchingNotification(gNotifyPort, // notifyPort
-                kIOFirstMatchNotification, // notificationType
-                matchingDict, // matching
-                DeviceAdded, // callback
-                NULL, // refCon
-                &gAddedIter[i] // notification
-                );
-
-        // Iterate once to get already-present devices and arm the notification
-        //
-        DeviceAdded(NULL, gAddedIter[i]);
-    }
+       // Set up the matching criteria for the devices we're interested in.  The matching criteria needs to follow
+       // the same rules as kernel drivers:  mainly it needs to follow the USB Common Class Specification, pp. 6-7.
+       // See also http://developer.apple.com/qa/qa2001/qa1076.html
+       // One exception is that you can use the matching dictionary "as is", i.e. without adding any matching criteria
+       // to it and it will match every IOUSBDevice in the system.  IOServiceAddMatchingNotification will consume this
+       // dictionary reference, so there is no need to release it later on.
+       //
+       matchingDict = IOServiceMatching(kIOUSBInterfaceClassName); // Interested in instances of class
+                                                                                                                               // IOUSBInterface and its subclasses
+       if (!matchingDict) {
+               LOG_DEBUG("Can't create a USB matching dictionary\n");
+               mach_port_deallocate(mach_task_self(), masterPort);
+               return;
+       }
+
+       LOG_DEBUG("Looking for devices matching vendor ID=%0x(%0x, %0x)\n", usbVendor, subClass, protocol);
+
+       // We are interested in all USB Devices (as opposed to USB interfaces).  The Common Class Specification
+       // tells us that we need to specify the idVendor, idProduct, and bcdDevice fields, or, if we're not interested
+       // in particular bcdDevices, just the idVendor and idProduct.  Note that if we were trying to match an IOUSBInterface,
+       // we would need to set more values in the matching dictionary (e.g. idVendor, idProduct, bInterfaceNumber and
+       // bConfigurationValue.
+       //
+
+       // Create a CFNumber for the idVendor, interface subclass and protocol and set the value in the dictionary
+       //
+       numberRef = 0;
+
+       // Now set up a notification to be called when a device is first matched by I/O Kit.
+       // Note that this will not catch any devices that were already plugged in so we take
+       // care of those later.
+       //
+       kr = IOServiceAddMatchingNotification(gNotifyPort, // notifyPort
+                       kIOFirstMatchNotification, // notificationType
+                       matchingDict, // matching
+                       DeviceAdded, // callback
+                       NULL, // refCon
+                       &gAddedIter[i] // notification
+                       );
+
+       // Iterate once to get already-present devices and arm the notification
+       //
+       DeviceAdded(NULL, gAddedIter[i]);
 
     // Now done with the master_port
     mach_port_deallocate(mach_task_self(), masterPort);