Mam zaimplementowaną funkcję wykrywania urządzenia USB. Działa i teraz muszę wysłać/odczytać dane.Dane wysyłania/odbierania urządzenia USB
zacząłem patrzeć na wiele obj-c
źródeł i znalazłem tylko jedną dobrą article w dokumentacji jabłkowego, który opisuje w jaki sposób możemy wysłać paczkę do naszego urządzenia USB:
IOReturn WriteToDevice(IOUSBDeviceInterface **dev, UInt16 deviceAddress,
UInt16 length, UInt8 writeBuffer[])
{
IOUSBDevRequest request;
request.bmRequestType = USBmakebmRequestType(kUSBOut, kUSBVendor,
kUSBDevice);
request.bRequest = 0xa0;
request.wValue = deviceAddress;
request.wIndex = 0;
request.wLength = length;
request.pData = writeBuffer;
return (*dev)->DeviceRequest(dev, &request);
}
Ale nie znaleźć sposób tworzenia i wysyłania danych za pomocą Swift
. Struct na Swift
wygląda następująco:
public struct IOUSBDevRequest {
public var bmRequestType: UInt8
public var bRequest: UInt8
public var wValue: UInt16
public var wIndex: UInt16
public var wLength: UInt16
public var pData: UnsafeMutableRawPointer!
public var wLenDone: UInt32
public init()
public init(bmRequestType: UInt8, bRequest: UInt8, wValue: UInt16, wIndex: UInt16, wLength: UInt16, pData: UnsafeMutableRawPointer!, wLenDone: UInt32)
}
nie mogę dowiedzieć się, jakie parametry ma pData
, zwLenDone
.
Są to dane, które trzeba wysłać:
{
'direction':'in',
'recipient':'device',
'requestType': 'standard',
'request': 6,
'value': 0x300,
'index': 0,
'length': 255
}
Kolejne pytanie brzmi: Jak mogę odbierać dane. Wiem, że odpowiedź jest w tym artykule, ale nie mogę go przekonwertować na Swift.
Oto, co mogłem przekonwertować na Swift 3
. Moja klasa wykrywa USB
urządzenie, uzyskać jego konfigurację:
class DFUDevice: NSObject {
let vendorId = 0x0483
let productId = 0xdf11
static let sharedInstance = DFUDevice()
var deviceName:String = ""
private func deviceAdded(iterator: io_iterator_t) {
var plugInInterfacePtrPtr: UnsafeMutablePointer<UnsafeMutablePointer<IOCFPlugInInterface>?>?
var deviceInterfacePtrPtr: UnsafeMutablePointer<UnsafeMutablePointer<IOUSBDeviceInterface>?>?
var configPtr:IOUSBConfigurationDescriptorPtr?
var score: Int32 = 0
while case let usbDevice = IOIteratorNext(iterator), usbDevice != 0 {
// 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](repeating: 0, count: 128)
let deviceNameResult = IORegistryEntryGetName(usbDevice, &deviceNameCString)
if(deviceNameResult != kIOReturnSuccess) {
print("Error getting device name")
}
self.deviceName = String.init(cString: &deviceNameCString)
print("usb Device Name: \(deviceName)")
// Get plugInInterface for current USB device
let plugInInterfaceResult = IOCreatePlugInInterfaceForService(
usbDevice,
kIOUSBDeviceUserClientTypeID,
kIOCFPlugInInterfaceID,
&plugInInterfacePtrPtr,
&score)
// dereference pointer for the plug in interface
guard plugInInterfaceResult == kIOReturnSuccess,
let plugInInterface = plugInInterfacePtrPtr?.pointee?.pointee else {
print("Unable to get Plug-In Interface")
continue
}
// use plug in interface to get a device interface
let deviceInterfaceResult = withUnsafeMutablePointer(to: &deviceInterfacePtrPtr) {
$0.withMemoryRebound(to: Optional<LPVOID>.self, capacity: 1) {
plugInInterface.QueryInterface(
plugInInterfacePtrPtr,
CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID),
$0)
}
}
// dereference pointer for the device interface
guard deviceInterfaceResult == kIOReturnSuccess,
let deviceInterface = deviceInterfacePtrPtr?.pointee?.pointee else {
print("Unable to get Device Interface")
continue
}
var ret = deviceInterface.USBDeviceOpen(deviceInterfacePtrPtr)
if (ret == kIOReturnSuccess)
{
// set first configuration as active
ret = deviceInterface.GetConfigurationDescriptorPtr(deviceInterfacePtrPtr, 0, &configPtr)
if (ret != kIOReturnSuccess)
{
print("Could not set active configuration (error: %x)\n", ret);
continue
}
guard let config = configPtr?.pointee else {
continue
}
if config.bLength > 0 {
//HERE I NEED SEND DATA
} else {
print("ConfigurationDescriptor not valid")
}
print(config.bLength)
}
else if (ret == kIOReturnExclusiveAccess)
{
// this is not a problem as we can still do some things
}
else
{
print("Could not open device (error: %x)\n", ret)
continue
}
IOObjectRelease(usbDevice)
}
}
func initUsb() {
var matchedIterator:io_iterator_t = 0
var removalIterator:io_iterator_t = 0
let notifyPort:IONotificationPortRef = IONotificationPortCreate(kIOMasterPortDefault)
IONotificationPortSetDispatchQueue(notifyPort, DispatchQueue(label: "IODetector"))
let matchingDict = IOServiceMatching(kIOUSBDeviceClassName)
as NSMutableDictionary
matchingDict[kUSBVendorID] = NSNumber(value: self.vendorId)
matchingDict[kUSBProductID] = NSNumber(value: self.productId)
let matchingCallback:IOServiceMatchingCallback = { (userData, iterator) in
let this = Unmanaged<DFUDevice>
.fromOpaque(userData!).takeUnretainedValue()
this.deviceAdded(iterator: iterator)
this.connected(iterator: iterator)
}
let removalCallback: IOServiceMatchingCallback = {
(userData, iterator) in
let this = Unmanaged<DFUDevice>
.fromOpaque(userData!).takeUnretainedValue()
this.disconnected(iterator: iterator)
}
let selfPtr = Unmanaged.passUnretained(self).toOpaque()
IOServiceAddMatchingNotification(notifyPort, kIOFirstMatchNotification, matchingDict, matchingCallback, selfPtr, &matchedIterator)
IOServiceAddMatchingNotification(notifyPort, kIOTerminatedNotification, matchingDict, removalCallback, selfPtr, &removalIterator)
self.deviceAdded(iterator: matchedIterator)
self.deviceAdded(iterator: removalIterator)
RunLoop.current.run()
}
}
nazywam go tak:
let DFUDeviceDaemon = Thread(target: DFUDevice.sharedInstance, selector:#selector(DFUDevice.initUsb), object: nil)
DFUDeviceDaemon.start()
ORSSerialPort, napisany przez Andrew Madsen, to doskonały zarówno biblioteki napisane w Objective-C i Swift (która wersja nie jestem pewien). Nawet jeśli nie jest to tym, czego szukasz, kod źródłowy może pomóc ci ustawić właściwą drogę. https://github.com/armadsen/ORSSerialPort –
Utworzyłem bibliotekę [USBDeviceSwift] (https://github.com/Arti3DPlayer/USBDeviceSwift) dla wygodnej pracy z 'IOKit.usb' i' IOKit.hid' – Arti