Skip to content

Instantly share code, notes, and snippets.

@zachbadgett
Created December 15, 2015 16:29
Show Gist options
  • Save zachbadgett/471d72e83fee413d0f38 to your computer and use it in GitHub Desktop.
Save zachbadgett/471d72e83fee413d0f38 to your computer and use it in GitHub Desktop.
import Foundation
import IOKit
import IOKit.usb
import IOKit.usb.IOUSBLib
print("Scanning USB Bus.....\n\n\n")
//
// These constants are not imported into Swift from IOUSBLib.h as they
// are all #define constants
//
let kIOUSBDeviceUserClientTypeID: CFUUID = CFUUIDGetConstantUUIDWithBytes(kCFAllocatorDefault,
0x9d, 0xc7, 0xb7, 0x80, 0x9e, 0xc0, 0x11, 0xD4,
0xa5, 0x4f, 0x00, 0x0a, 0x27, 0x05, 0x28, 0x61)
let kIOCFPlugInInterfaceID: CFUUID = CFUUIDGetConstantUUIDWithBytes(kCFAllocatorDefault,
0xC2, 0x44, 0xE8, 0x58, 0x10, 0x9C, 0x11, 0xD4,
0x91, 0xD4, 0x00, 0x50, 0xE4, 0xC6, 0x42, 0x6F)
let kIOUSBDeviceInterfaceID: CFUUID = CFUUIDGetConstantUUIDWithBytes(kCFAllocatorDefault,
0x5c, 0x81, 0x87, 0xd0, 0x9e, 0xf3, 0x11, 0xD4,
0x8b, 0x45, 0x00, 0x0a, 0x27, 0x05, 0x28, 0x61)
var usbIterator: io_iterator_t = io_iterator_t()
var usbDevice: io_service_t = io_service_t()
var usbVendorID: UInt16 = 0
var score: Int32 = 0
var plugInInterfacePtrPtr = UnsafeMutablePointer<UnsafeMutablePointer<IOCFPlugInInterface>>()
// From: CFPlugInCOM.h: public typealias LPVOID = UnsafeMutablePointer<Void>()
var deviceInterfaceVoidPtr = UnsafeMutablePointer<Void>()
// create dictionary with IOUSBDevice as IOProviderClass
let matchingDictionary: NSMutableDictionary = IOServiceMatching(kIOUSBDeviceClassName)
// get iterator for matching USB devices
let matchingServicesResult = IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDictionary, &usbIterator)
if (matchingServicesResult != kIOReturnSuccess) {
print("Error getting deviceList!")
exit(EXIT_FAILURE)
}
// usbDevice = 0 when finished iterating all devices
repeat {
usbDevice = IOIteratorNext(usbIterator)
// io_name_t imports to swift as a tuple (Int8, ..., Int8) 128 ints
// although in device_types.h it's defined:
// typedef char io_name_t[128];
var deviceNameCString: [CChar] = [CChar](count: 128, repeatedValue: 0)
let deviceNameResult = IORegistryEntryGetName(usbDevice, &deviceNameCString)
if(deviceNameResult != kIOReturnSuccess) {
print("Error getting device name")
exit(EXIT_FAILURE)
}
let deviceName = String.fromCString(&deviceNameCString)!
print("usb Device Name: \(deviceName)")
// Get plugInInterface for current USB device
let plugInInterfaceResult = IOCreatePlugInInterfaceForService(
usbDevice,
kIOUSBDeviceUserClientTypeID,
kIOCFPlugInInterfaceID,
&plugInInterfacePtrPtr,
&score)
if ( (plugInInterfacePtrPtr == nil) || (plugInInterfaceResult != kIOReturnSuccess)) {
print("Unable to get Plug-In Interface")
continue
}
// dereference pointer for the plug in interface
let plugInInterface: IOCFPlugInInterface = plugInInterfacePtrPtr.memory.memory
// use plug in interface to get a device interface
// public var QueryInterface: (@convention(c) (UnsafeMutablePointer<Void>, REFIID, UnsafeMutablePointer<LPVOID>) -> HRESULT)!
let deviceInterfaceResult = plugInInterface.QueryInterface(
plugInInterfacePtrPtr,
CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID),
&deviceInterfaceVoidPtr)
if( (deviceInterfaceResult != kIOReturnSuccess) || (deviceInterfaceVoidPtr == nil) ) {
print("Unable to get Device Interface")
exit(EXIT_FAILURE)
}
// dereference the IOUSBDeviceInterface struct from pointer var after
// converting from a void to a IOUSBDeviceInterface pointer
let deviceInterface = (UnsafeMutablePointer<IOUSBDeviceInterface>(deviceInterfaceVoidPtr)).memory
// get USB Vendor ID --> CRASH
let vendorResult = deviceInterface.GetDeviceVendor(deviceInterfaceVoidPtr, &usbVendorID)
if(vendorResult != kIOReturnSuccess) {
print("Unable to get Device Vendor ID")
exit(EXIT_FAILURE)
}
print("usb Vendor ID: \(usbVendorID)")
usbDevice = IOIteratorNext(usbIterator)
} while (usbDevice != 0);
exit(EXIT_SUCCESS)
@cellininicholas
Copy link

Hey!
You shouldn't have

usbDevice = IOIteratorNext(usbIterator)

on the first AND last line of your loop, you are skipping over elements from the iterator

@Arti3DPlayer
Copy link

I have created USBDeviceSwift library for convenient work with IOKit.usb and IOKit.hid

@Mikegim
Copy link

Mikegim commented Oct 9, 2017

@Arti3DPlayer
I started very little to study to program for Mac OSX, as by Apple's advice I'm studying Swift, I just updated to Xcode9 with swift 4.
I wanted to use the USB and found your USBDeviceSwift project interesting, only I have difficulty using it.
I followed the instructions to install the wrap only through cocoapods.
I get an error in the line:

let stm32DeviceMonitor = USBDeviceMonitor ([
         VIDPID (vendorId: 0x0483, productId: 0xdf11)
     ])
  
What can it depend on?
Greetings
Mike

@Mikegim
Copy link

Mikegim commented Oct 9, 2017

the VIDPID command is not recognized.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment