Last active
June 4, 2023 02:27
-
-
Save zhen-zen/ce4d3108aaa6f8855e2f04fb0047c795 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 8152Info.swift | |
// 8152Info | |
// | |
// Created by Zhen on 3/24/21. | |
// | |
import Foundation | |
import IOKit.usb | |
import IOKit.usb.IOUSBLib | |
// from https://github.com/Arti3DPlayer/USBDeviceSwift/blob/master/Sources/USBDevice.swift | |
// from IOUSBLib.h | |
public let kIOUSBDeviceUserClientTypeID = CFUUIDGetConstantUUIDWithBytes(nil, | |
0x9d, 0xc7, 0xb7, 0x80, 0x9e, 0xc0, 0x11, 0xD4, | |
0xa5, 0x4f, 0x00, 0x0a, 0x27, 0x05, 0x28, 0x61) | |
public let kIOUSBDeviceInterfaceID = CFUUIDGetConstantUUIDWithBytes(nil, | |
0x5c, 0x81, 0x87, 0xd0, 0x9e, 0xf3, 0x11, 0xD4, | |
0x8b, 0x45, 0x00, 0x0a, 0x27, 0x05, 0x28, 0x61) | |
// from IOCFPlugin.h | |
public let kIOCFPlugInInterfaceID = CFUUIDGetConstantUUIDWithBytes(nil, | |
0xC2, 0x44, 0xE8, 0x58, 0x10, 0x9C, 0x11, 0xD4, | |
0x91, 0xD4, 0x00, 0x50, 0xE4, 0xC6, 0x42, 0x6F) | |
let RTL8152_REQT_READ: UInt8 = 0xc0 | |
let RTL8152_REQ_GET_REGS: UInt8 = 0x05 | |
let PLA_TCR0: UInt16 = 0xe610 | |
let MCU_TYPE_PLA: UInt16 = 0x0100 | |
let VERSION_MASK: UInt32 = 0x7cf0 | |
let idVendor: Int32 = 0x0bda | |
let idProduct: Int32 = 0x8156 | |
let idProductArray: NSMutableArray = [0x8152, 0x8153, 0x8156] | |
var device: UnsafeMutablePointer<UnsafeMutablePointer<IOUSBDeviceInterface>?>? | |
var plugin: UnsafeMutablePointer<UnsafeMutablePointer<IOCFPlugInInterface>?>? | |
var score: Int32 = 0 | |
var reg: UInt32 = 0 | |
var kr: kern_return_t = 0 | |
var iter: io_iterator_t = 0 | |
// from https://github.com/LinusHenze/Fugu/blob/master/USB/IOKitUSB.swift | |
// IOIteratorNext, Swift Style | |
func IOIteratorNextOptional(_ iterator: io_iterator_t) -> io_service_t? { | |
let service = IOIteratorNext(iterator) | |
return service != 0 ? service : nil | |
} | |
var matchingDictionary: NSMutableDictionary = IOServiceMatching(kIOUSBDeviceClassName) | |
matchingDictionary[kUSBVendorID] = idVendor as NSNumber | |
//matchingDictionary[kUSBProductID] = idProduct as NSNumber | |
matchingDictionary[kUSBProductIdsArrayName] = idProductArray | |
kr = IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDictionary, &iter) | |
guard kr == kIOReturnSuccess else { exit(-1) } | |
print("Enumerating RTL8152 devices") | |
while let usbRef = IOIteratorNextOptional(iter) { | |
var deviceNameCString: [CChar] = [CChar](repeating: 0, count: 128) | |
kr = IORegistryEntryGetName(usbRef, &deviceNameCString) | |
if kr != kIOReturnSuccess { | |
print("Error getting device name") | |
} | |
print("Found:", String(cString: &deviceNameCString)) | |
kr = IOCreatePlugInInterfaceForService(usbRef, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugin, &score) | |
guard kr == kIOReturnSuccess else { | |
print("Unable to create PlugIn Interface for Device", kr) | |
continue | |
} | |
IOObjectRelease(usbRef) | |
guard let pluginInterface = plugin?.pointee?.pointee else { | |
print("Unable to get Plugin Interface") | |
continue | |
} | |
kr = withUnsafeMutablePointer(to: &device) { | |
$0.withMemoryRebound(to: Optional<LPVOID>.self, capacity: 1) { | |
pluginInterface.QueryInterface( | |
plugin, | |
CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), | |
$0) | |
} | |
} | |
guard kr == kIOReturnSuccess else { | |
print("Unable to query Device") | |
continue | |
} | |
_ = pluginInterface.Release(plugin) | |
guard let deviceInterface = device?.pointee?.pointee else { | |
print("Unable to get Device Interface") | |
continue | |
} | |
kr = deviceInterface.USBDeviceOpen(device) | |
guard kr == kIOReturnSuccess else { | |
if kr == kIOReturnExclusiveAccess{ | |
print("Unable to gain Access") | |
} else { | |
print("Unable to open Device") | |
} | |
continue | |
} | |
var request = IOUSBDevRequest( | |
bmRequestType: RTL8152_REQT_READ, | |
bRequest: RTL8152_REQ_GET_REGS, | |
wValue: PLA_TCR0, | |
wIndex: MCU_TYPE_PLA, | |
wLength: 4, | |
pData: ®, | |
wLenDone: 4 | |
) | |
kr = deviceInterface.DeviceRequest(device, &request) | |
if kr != kIOReturnSuccess { | |
print("Unable to send Device request") | |
} else { | |
print(String(format:"PLA_TCR0: 0x%08X", reg)) | |
let ver = reg >> 16 & VERSION_MASK | |
print(String(format:"Version: 0x%04X", ver)) | |
switch ver { | |
case 0x4c00: | |
print("RTL_VER_01 - RT8152B") | |
case 0x4c10: | |
print("RTL_VER_02 - RT8152B") | |
case 0x5c00: | |
print("RTL_VER_03 - RT8153") | |
case 0x5c10: | |
print("RTL_VER_04 - RT8153") | |
case 0x5c20: | |
print("RTL_VER_05 - RT8153") | |
case 0x5c30: | |
print("RTL_VER_06 - RT8153") | |
case 0x4800: | |
print("RTL_VER_07 - RT8152B") | |
case 0x6000: | |
print("RTL_VER_08 - RT8153B") | |
case 0x6010: | |
print("RTL_VER_09 - RT8153B") | |
case 0x7010: | |
print("RTL_TEST_01 - RT8156") | |
case 0x7020: | |
print("RTL_VER_10 - RT8156") | |
case 0x7030: | |
print("RTL_VER_11 - RT8156") | |
case 0x7400: | |
print("RTL_VER_12 - RT8156B") | |
case 0x7410: | |
print("RTL_VER_13 - RT8156B") | |
case 0x6400: | |
print("RTL_VER_14 - RTL8153C") | |
default: | |
print("RTL_VER_UNKNOWN"); | |
} | |
} | |
kr = deviceInterface.USBDeviceClose(device) | |
guard kr == kIOReturnSuccess else { | |
print("Unable to close Device") | |
continue | |
} | |
_ = deviceInterface.Release(device) | |
} | |
IOObjectRelease(iter) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment