Mac OSX 读写usb composite设备

看了Apple上的资料(真是又多又臭,组织真烂,还是E文的),说是针对不同的pid和vid的composite usb设备,

只需要写一个codeless驱动就可以提供对该设备的访问。但是本人对Mac开发不熟,更不用说是驱动开发了。捣鼓

好久没整出个能用的驱动,虽然说是codeless驱动。

船到桥头自然直吧,看资料时发现,既然是composite usb设备,又说是codeless驱动,也就是说,即使不用驱动,

直接就可以通过MACH的api来访问指定vid和pid的设备了吧,最后整出这个类,目前测试未发现问题。

  1 //
  2 //  MyUSBDevice.h
  3 //  4 //
  5 //  Created by Jojo on 12-6-7.
  6 //  Copyright (c) 2012年 Mars. All rights reserved.
  7 //
  8 
  9 
 10 #ifndef MyUSB_Device_h
 11 #define MyUSB_Device_h
 12 
 13 #include <vector>
 14 
 15 #include <CoreFoundation/CoreFoundation.h>
 16 #include <IOKit/usb/IOUSBLib.h>
 17 #include <IOKit/IOCFPlugIn.h>
 18 #include <mach/mach.h>
 19 
 20 typedef void * HANDLE;
 21 typedef char * PCHAR;
 22 typedef unsigned int u32;
 23 typedef unsigned char u8;
 24 typedef unsigned char BYTE;
 25 typedef unsigned int DWORD;
 26 typedef unsigned short WORD;
 27 
 28 using namespace std;
 29 
 30 class MyUSBDevice {
 31 private:
 32     static MyUSBDevice        *uniqueObj;
 33     static SInt32                refCount;
 34 public:
 35     typedef struct tag_usbHandle {
 36         IOUSBDeviceInterface    **dev;
 37         IOUSBInterfaceInterface    **interface;
 38         UInt8                    pipeIn;
 39         UInt8                    pipeOut;
 40         UInt16                    maxPacketSizeIn;
 41         UInt16                    maxPacketSizeOut;
 42         UInt32                    locationID;
 43     }UsbHandle;
 44 private:    
 45     vector<UsbHandle *> devVector;
 46 public:
 47     /* The only way to create the class driver instance is the allocate method */
 48     static MyUSBDevice* Allocate(void);
 49     
 50     /* Get the instance of this class */
 51     static MyUSBDevice * GetInstance(void) { return uniqueObj; }
 52     
 53     /* Before any operation the instance should have been initialized */
 54     IOReturn initialize(void);
 55     
 56     /* Get the UsbHandle pointer at nIndex */
 57     HANDLE GetDeviceHandle(u32 nIndex);
 58     
 59     /* Release the class if you don't need it anymore */
 60     void Release(UsbHandle *dev);
 61         
 62     /* Write data into the in bulk pipe synchronous or asynchronous */
 63     IOReturn WriteSync(UsbHandle *dev, void *buff, u32 size);
 64     IOReturn WriteAsync(UsbHandle *dev, void *buff, u32 size, u32 *pWrite);
 65     
 66     /* Read data from the out bulk pipe synchronous or asynchronous */
 67     IOReturn ReadSync(UsbHandle *dev, void *buff, u32 *pSize);
 68     IOReturn ReadAsync(UsbHandle *dev, void *buff, u32 size, u32 *pRead);
 69     
 70     /* 
 71      Sends a USB request with a command on the default control pipe.
 72      request command below:
 73      
 74      enum {
 75      kUSBRqGetStatus     = 0,
 76      kUSBRqClearFeature  = 1,
 77      kUSBRqGetState      = 2,
 78      kUSBRqSetFeature    = 3,
 79      kUSBRqReserved2     = 4,
 80      kUSBRqSetAddress    = 5,
 81      kUSBRqGetDescriptor = 6,
 82      kUSBRqSetDescriptor = 7,
 83      kUSBRqGetConfig     = 8,
 84      kUSBRqSetConfig     = 9,
 85      kUSBRqGetInterface  = 10,
 86      kUSBRqSetInterface  = 11,
 87      kUSBRqSyncFrame     = 12
 88      };     
 89      */
 90     IOReturn DeviceRequestSync(UsbHandle *dev, UInt8 cmd , UInt16 deviceAddress, 
 91                            UInt16 length, UInt8 *Buffer);
 92     IOReturn DeviceRequestAsync(UsbHandle *dev, UInt8 cmd , UInt16 deviceAddress, 
 93                            UInt16 length, UInt8 *Buffer);
 94 private:
 95     MyUSBDevice();
 96     ~MyUSBDevice();
 97     IOReturn GetUSBInterface(io_iterator_t iterator);
 98     IOReturn FindUSBInterface(IOUSBDeviceInterface **dev);
 99     bool IsDeviceExist(IOUSBDeviceInterface **dev);
100     static void OperationCallBack(void *refcon, IOReturn result, void *arg0);
101 };
102 
103 #endif
  1 //
  2 //  MyUSBDevice.cpp
  3 //  4 //
  5 //  Created by Jojo on 12-6-7.
  6 //  Copyright (c) 2012 Mars Company LTD. All rights reserved.
  7 //
  8 
  9 
 10 #include "MyUSBDevice.h"
 11 
 12 #define kOurVendorID    0x1f3a  //设备的vendor ID
 13 #define kOurProductID   0xefe8  //设备的Product ID
 14 
 15 SInt32 MyUSBDevice::refCount = 0;
 16 MyUSBDevice* MyUSBDevice::uniqueObj = NULL;
 17 
 18 MyUSBDevice* MyUSBDevice::Allocate()
 19 {
 20     if (uniqueObj == NULL) {
 21         uniqueObj = new MyUSBDevice();
 22     }
 23     refCount++;
 24     return uniqueObj;
 25 }
 26 
 27 void MyUSBDevice::Release(UsbHandle *dev)
 28 {
 29     vector<UsbHandle *>::size_type i;
 30     vector<UsbHandle *>::iterator iter = devVector.begin();
 31     for (i = 0; i < devVector.size(); i++, iter++) {
 32         UsbHandle *tmp = devVector.at(i);
 33         if (dev->dev == tmp->dev) {
 34             (*(tmp->interface))->USBInterfaceClose(tmp->interface);
 35             (*(tmp->interface))->Release(tmp->interface);
 36             (*(tmp->dev))->USBDeviceClose(tmp->dev);
 37             (*(tmp->dev))->Release(tmp->dev);            
 38             delete tmp;
 39             devVector.erase(iter);
 40             break;
 41         }
 42     }
 43     
 44     refCount--;
 45     if (refCount == 0) {
 46         delete uniqueObj;
 47         uniqueObj = NULL;
 48     }
 49 }
 50 
 51 MyUSBDevice::MyUSBDevice()
 52 {
 53     devVector.clear();
 54 }
 55 
 56 MyUSBDevice::~MyUSBDevice()
 57 {
 58     vector<UsbHandle *>::size_type i;
 59     for (i = 0; i < devVector.size(); i++) {
 60         UsbHandle *tmp = devVector.at(i);        
 61         (*(tmp->interface))->USBInterfaceClose(tmp->interface);
 62         (*(tmp->interface))->Release(tmp->interface);
 63         (*(tmp->dev))->USBDeviceClose(tmp->dev);
 64         (*(tmp->dev))->Release(tmp->dev);
 65         delete tmp;
 66     }
 67     devVector.clear();
 68 }
 69 
 70 IOReturn MyUSBDevice::initialize(void)
 71 {
 72     mach_port_t                masterPort;
 73     CFMutableDictionaryRef    matchingDict;
 74     kern_return_t            kr;
 75     SInt32                    usbVendor = kOurVendorID;
 76     SInt32                    usbProduct = kOurProductID;
 77     io_iterator_t            iter;
 78     
 79     
 80     kr = IOMasterPort(MACH_PORT_NULL, &masterPort);
 81     if(kr != kIOReturnSuccess || !masterPort) {
 82         printf("Unable to create a master I/O Kit port (%08x)\n", kr);
 83         return kIOReturnAborted;
 84     }
 85     
 86     //Set up matching dictionary for class IOUSBDevice and its subclass
 87     matchingDict = IOServiceMatching(kIOUSBDeviceClassName);
 88     if(!matchingDict) {
 89         printf("Unable to create a USB matching dictionary (%08x)\n", kr);
 90         return kIOReturnAborted;
 91     }
 92     
 93     //Add the vendor and product IDs to the matching dictionary
 94     CFDictionarySetValue(matchingDict, CFSTR(kUSBVendorName), 
 95                          CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &usbVendor));
 96     CFDictionarySetValue(matchingDict, CFSTR(kUSBProductName), 
 97                          CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &usbProduct));
 98     
 99     //Look up registered IOService objects that match a matching dictionary
100     kr = IOServiceGetMatchingServices(masterPort, matchingDict, &iter);
101     if (kr != kIOReturnSuccess) {
102         mach_port_deallocate(mach_task_self(), masterPort);
103         return kr;
104     }
105     
106     //Get the usb device interface
107     kr = GetUSBInterface(iter);
108     if (kr != kIOReturnSuccess) {
109         mach_port_deallocate(mach_task_self(), masterPort);
110         IOObjectRelease(iter);
111         return kr;
112     }
113     
114     IOObjectRelease(iter);
115     mach_port_deallocate(mach_task_self(), masterPort);
116     
117     return kIOReturnSuccess;
118 }
119 
120 IOReturn MyUSBDevice::GetUSBInterface(io_iterator_t iterator)
121 {
122     kern_return_t            kr;
123     io_service_t            usbDevice;
124     IOCFPlugInInterface        **plugInInterface = NULL;
125     IOUSBDeviceInterface    **dev = NULL;
126     HRESULT                    result;
127     SInt32                    score;
128     UInt16                    vendor;
129     UInt16                    product;
130     UInt16                    release;
131     UInt32                    locationID;
132     
133     while((usbDevice = IOIteratorNext(iterator))) {
134         //Create an intermediate plug-in
135         kr = IOCreatePlugInInterfaceForService(usbDevice, kIOUSBDeviceUserClientTypeID, 
136                                                kIOCFPlugInInterfaceID, &plugInInterface, &score);
137         //Don't need the device object after intermediate plug-in is created
138         kr = IOObjectRelease(usbDevice);
139         if(kr != kIOReturnSuccess || !plugInInterface) {
140             printf("Unable to create a plug-in (%08x)\n", kr);
141             continue;
142         }
143         
144         //Now create the device interface
145         result = (*plugInInterface)->QueryInterface(plugInInterface, 
146                         CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (LPVOID *)&dev);
147         //Don't need the device object after intermediate plug-in is created
148         IODestroyPlugInInterface(plugInInterface);
149         if(result || !dev) {
150             printf("Unable to create a device interface (%08x)\n", 
151                    (int)result);
152             continue;
153         }
154         if (IsDeviceExist(dev) == true) {
155             (*dev)->Release(dev);
156             dev = NULL;
157             continue;
158         }
159         
160         //Check these values for confirmation
161         kr = (*dev)->GetDeviceVendor(dev, &vendor);
162         kr = (*dev)->GetDeviceProduct(dev, &product);
163         kr = (*dev)->GetDeviceReleaseNumber(dev, &release);
164         kr = (*dev)->GetLocationID(dev, &locationID);
165         
166         if(vendor != kOurVendorID || product != kOurProductID) {
167             printf("Found unwanted device (vendor %d, product %d)\n", 
168                    vendor, product);
169             (void) (*dev)->Release(dev);
170             dev = NULL;
171             continue;
172         } else {
173             printf("Found allwinner usb device (vendor %d, product %d), location id %08x\n", 
174                    vendor, product, locationID);
175             //Open the device to change its state
176             kr = (*dev)->USBDeviceOpen(dev);
177             if(kr != kIOReturnSuccess) {
178                 printf("Unable to open usb device: %08x\n", kr);
179                 (void) (*dev)->Release(dev);
180                 dev = NULL;
181                 continue;
182             }
183             
184             //configure device
185             UInt8                numConfig;
186             IOUSBConfigurationDescriptorPtr configDesc;
187             
188             //Get the number of configurations.
189             kr = (*dev)->GetNumberOfConfigurations(dev, &numConfig);
190             if(numConfig == 0)
191                 continue;
192             
193             //Get the configuration descriptor for index 0
194             kr = (*dev)->GetConfigurationDescriptorPtr(dev, 0, &configDesc);
195             if(kr) {
196                 printf("Unable to get configuration descriptor for index 0 (err = %08x)\n", 
197                        kr);
198                 continue;
199             }
200 #if 0            
201             //Set the device's configuration. The configuration value is found in
202             //the bConfigurationValue field of the configuration descriptor
203             kr = (*dev)->SetConfiguration(dev, configDesc->bConfigurationValue);
204             if(kr) {
205                 printf("Unable to set configuration to value %d (err = %08x)\n", 
206                        0, kr);
207                 continue;
208             }
209 #endif
210             kr = FindUSBInterface(dev);
211             if (kr != kIOReturnSuccess) {
212                 (*dev)->USBDeviceClose(dev);
213                 (*dev)->Release(dev);
214                 dev = NULL;
215             }
216         }
217     }
218     return kr;
219 }
220 
221 IOReturn MyUSBDevice::FindUSBInterface(IOUSBDeviceInterface **dev)
222 {    
223     IOReturn                    kr;
224     IOUSBFindInterfaceRequest    request;
225     io_iterator_t                iterator;
226     io_service_t                usbInterface;
227     IOCFPlugInInterface            **plugInInterface = NULL;
228     IOUSBInterfaceInterface        **interface = NULL;
229     HRESULT                        result;
230     SInt32                        score;
231     UInt8                        interfaceNumEndpoints;
232     UInt8                        pipeRef;
233     UInt16                        maxPacketSize = 0;
234     UInt8                        pipeIn = 0xff;
235     UInt8                        pipeOut = 0xff;
236     UInt16                        maxPacketSizeIn = 0;
237     UInt16                        maxPacketSizeOut = 0;
238     
239     //Iterate all usb interface
240     request.bInterfaceClass = kIOUSBFindInterfaceDontCare;
241     request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
242     request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
243     request.bAlternateSetting = kIOUSBFindInterfaceDontCare;
244     
245     //Get an iterator for the interfaces on the device
246     kr = (*dev)->CreateInterfaceIterator(dev, &request, &iterator);
247     if(kr != kIOReturnSuccess) {
248         printf("Unable to CreateInterfaceIterator %08x\n", kr);
249         return kr;
250     }
251 
252     while((usbInterface = IOIteratorNext(iterator))) {
253         pipeIn = 0xff;
254         pipeOut = 0xff;
255         //Create a intermediate plug-in
256         kr = IOCreatePlugInInterfaceForService(usbInterface, 
257                                                kIOUSBInterfaceUserClientTypeID, kIOCFPlugInInterfaceID, 
258                                                &plugInInterface, &score);
259         //Release the usbInterface object after getting the plug-in
260         kr = IOObjectRelease(usbInterface);
261         if(kr != kIOReturnSuccess || !plugInInterface) {
262             printf("Unable to create a plug-in (%08x)\n", kr);
263             break;
264         }
265         
266         //Now create the device interface for the device interface
267         result = (*plugInInterface)->QueryInterface(plugInInterface, 
268                             CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID), (LPVOID *)&interface);
269         IODestroyPlugInInterface(plugInInterface);
270         if(result || !interface) {
271             printf("Unable to create a interface for the device interface %08x\n", 
272                    (int)result);
273             break;
274         }
275                 
276         //Now open the interface.This will cause the pipes associated with
277         //the endpoints in the interface descriptor to be instantiated
278         kr = (*interface)->USBInterfaceOpen(interface);
279         if(kr != kIOReturnSuccess) {
280             printf("Unable to open interface for the device interface %08x\n", kr);
281             (void) (*interface)->Release(interface);
282             interface = NULL;
283             break;
284         }
285         
286         //Get the number of endpoints associated with this interface
287         kr = (*interface)->GetNumEndpoints(interface, &interfaceNumEndpoints);
288         if(kr != kIOReturnSuccess) {
289             printf("Unable to get the number of endpoints %08x\n", kr);
290             (void) (*interface)->USBInterfaceClose(interface);
291             (void) (*interface)->Release(interface);
292             interface = NULL;
293             break;
294         }
295         
296         //Access each pipe in turn, starting with the pipe at index 1
297         //The pipe at index 0 is the default control pipe and should be
298         //accessed using (*usbDevice)->DeviceRequest() instead
299         for(pipeRef = 1; pipeRef <= interfaceNumEndpoints; pipeRef++) {
300             IOReturn     kr2;
301             UInt8        direction;
302             UInt8        number;
303             UInt8        transferType;
304             UInt8        interval;
305             
306             kr2 = (*interface)->GetPipeProperties(interface, pipeRef, &direction, 
307                                                   &number, &transferType, &maxPacketSize, &interval);
308             if(kr2 != kIOReturnSuccess) {
309                 printf("Unable to get properties of pipe %d (%08x)\n", 
310                        pipeRef, kr2);
311             } else {
312                 if(transferType == kUSBBulk) {
313                     if(direction == kUSBIn) {
314                         pipeIn = pipeRef;
315                         maxPacketSizeIn = maxPacketSize;
316                     }
317                     else if(direction == kUSBOut) {
318                         pipeOut = pipeRef;
319                         maxPacketSizeOut = maxPacketSize;
320                     }
321                 } 
322             }
323         }        
324         
325         if (pipeIn != 0xff && pipeOut != 0xff) {
326             UsbHandle *tmp = new UsbHandle;
327             tmp->dev = dev;
328             tmp->interface = interface;
329             tmp->pipeIn = pipeIn;
330             tmp->pipeOut = pipeOut;
331             tmp->maxPacketSizeIn = maxPacketSizeIn;
332             tmp->maxPacketSizeOut = maxPacketSizeOut;
333             (*dev)->GetLocationID(dev, &(tmp->locationID));
334             devVector.push_back(tmp);
335 
336             printf("Found %lu devices\n", devVector.size());
337 
338             return kIOReturnSuccess;
339         }
340         (*interface)->USBInterfaceClose(interface);
341         (*interface)->Release(interface);
342         interface = NULL;
343     }
344     
345     return kr;
346 }
347 
348 bool MyUSBDevice::IsDeviceExist(IOUSBDeviceInterface **dev)
349 {
350     if (!dev) {
351         return false;
352     }
353 
354     UInt32 locationID;
355     kern_return_t kr;
356     kr = (*dev)->GetLocationID(dev, &locationID);
357     if(kr != kIOReturnSuccess) {
358         printf("GetLocationID failed\n");
359         return false;
360     }
361     vector<UsbHandle *>::iterator iter = devVector.begin();
362     for (; iter != devVector.end(); iter++) {
363         UsbHandle *tmp = *iter;
364         if (tmp->locationID == locationID) {
365             return true;
366         }
367     }
368 
369     return false;
370 }
371 
372 IOReturn MyUSBDevice::WriteSync(UsbHandle *dev, void *buff, u32 size)
373 {
374     if (dev && dev->interface) {
375         if(size <= dev->maxPacketSizeOut) {
376             u32 writeLen;
377             return WriteAsync(dev, buff, size, &writeLen);
378         }
379         kern_return_t kr;
380         char *tmp = (char *)buff;
381         u32 nWrite = (size > dev->maxPacketSizeOut ? dev->maxPacketSizeOut : size);
382         u32 nLeft = size;
383 
384         while(1) {
385             if((int)nLeft <= 0) {
386                 break;
387             }
388             kr = (*(dev->interface))->WritePipe(dev->interface, 
389                     dev->pipeOut, (void *)tmp, nWrite);
390             if(kr != kIOReturnSuccess)
391                 break;
392             tmp += nWrite;
393             nLeft -= nWrite;
394             nWrite = (nLeft > dev->maxPacketSizeOut ? dev->maxPacketSizeOut : nLeft);
395         }
396         return kr;
397     }
398     
399     return kIOReturnNoDevice;
400 }
401 
402 IOReturn MyUSBDevice::WriteAsync(UsbHandle *dev, void *buff, u32 size, u32 *pWrite)
403 {
404     if (dev == NULL || dev->interface == NULL) {
405         return kIOReturnNoDevice;
406     }
407     
408     IOReturn                        err;
409     CFRunLoopSourceRef        cfSource;
410 
411     err = (*(dev->interface))->CreateInterfaceAsyncEventSource(dev->interface, &cfSource);
412     if (err)
413     {
414         printf("transferData: unable to create event source, err = %08x\n", err);
415         return err;
416     }
417     CFRunLoopAddSource(CFRunLoopGetCurrent(), cfSource, kCFRunLoopDefaultMode);
418     
419     err = (*(dev->interface))->WritePipeAsync(dev->interface, dev->pipeOut, (void *)buff, size, 
420                                          (IOAsyncCallback1)OperationCallBack, (void*)pWrite);
421     if (err != kIOReturnSuccess)
422     {
423         printf("transferData: WritePipeAsyncFailed, err = %08x\n", err);
424         CFRunLoopRemoveSource(CFRunLoopGetCurrent(), cfSource, kCFRunLoopDefaultMode);
425         *pWrite = 0;
426         return err;
427     }
428     
429     CFRunLoopRun();
430     CFRunLoopRemoveSource(CFRunLoopGetCurrent(), cfSource, kCFRunLoopDefaultMode);
431     
432     return err;
433 }
434 
435 IOReturn MyUSBDevice::ReadSync(UsbHandle *dev, void *buff, u32 *pSize)
436 {
437     if (dev && dev->interface) {
438         if(*pSize <= dev->maxPacketSizeIn)
439             return ReadAsync(dev, buff, *pSize, pSize);
440         kern_return_t kr;
441         UInt32 nRead = dev->maxPacketSizeIn;
442         u32 nLeft = *pSize;
443         char *tmp = (char *)buff;
444 
445         while(1) {
446             if((int)nLeft <= 0)
447                 break;
448 
449             kr = (*(dev->interface))->ReadPipe(dev->interface, 
450                     dev->pipeIn, (void *)tmp, &nRead);
451             if(kr != kIOReturnSuccess) {
452                 printf("transferData: Readsync Failed, err = %08x\n", kr);
453                 break;
454             }
455 
456             tmp += nRead;
457             nLeft -= nRead;
458             nRead = dev->maxPacketSizeIn;
459         }
460 
461         int nRet = ((int)nLeft > 0 ? nLeft : 0);
462         *pSize = *pSize - nRet;
463         return kr;
464     }
465     return kIOReturnNoDevice;
466 }
467 
468 IOReturn MyUSBDevice::ReadAsync(UsbHandle *dev, void *buff, u32 size, u32 *pRead)
469 {
470     if (dev == NULL || dev->interface == NULL) {
471         return kIOReturnNoDevice;
472     }
473     
474     IOReturn                err;
475     CFRunLoopSourceRef        cfSource;
476     
477     err = (*(dev->interface))->CreateInterfaceAsyncEventSource(dev->interface, &cfSource);
478     if (err)
479     {
480         printf("transferData: unable to create event source, err = %08x\n", err);
481         return err;
482     }
483     CFRunLoopAddSource(CFRunLoopGetCurrent(), cfSource, kCFRunLoopDefaultMode);
484     
485     err = (*(dev->interface))->ReadPipeAsync(dev->interface, dev->pipeIn, buff, size, 
486                                          (IOAsyncCallback1)OperationCallBack, (void*)pRead);
487     if (err != kIOReturnSuccess)
488     {
489         printf("transferData: size %u, ReadAsyncFailed, err = %08x\n", size, err);
490         CFRunLoopRemoveSource(CFRunLoopGetCurrent(), cfSource, kCFRunLoopDefaultMode);
491         *pRead = 0;
492         return err;
493     }
494     
495     CFRunLoopRun();
496     CFRunLoopRemoveSource(CFRunLoopGetCurrent(), cfSource, kCFRunLoopDefaultMode);
497     
498     return err;
499 }
500 
501 IOReturn MyUSBDevice::DeviceRequestAsync(UsbHandle *dev, UInt8 cmd, UInt16 deviceAddress, 
502                                              UInt16 length, UInt8 *Buffer)
503 {
504     if (dev->dev) {
505         IOReturn                        err;
506         CFRunLoopSourceRef        cfSource;
507         IOUSBDevRequest    request;                
508         
509         err = (*(dev->dev))->CreateDeviceAsyncEventSource(dev->dev, &cfSource);
510         if (err)
511         {
512             printf("transferData: unable to create event source, err = %08x\n", err);
513             return err;
514         }
515         CFRunLoopAddSource(CFRunLoopGetCurrent(), cfSource, kCFRunLoopDefaultMode);
516         
517         request.bmRequestType = USBmakebmRequestType(kUSBOut, kUSBVendor, kUSBDevice);
518         request.bRequest = cmd;
519         request.wValue = deviceAddress;
520         request.wIndex = 0;                //the default control pipe
521         request.wLength = length;
522         request.pData = Buffer;
523         
524         err = (*(dev->dev))->DeviceRequest(dev->dev, &request);
525         if (err != kIOReturnSuccess)
526         {
527             printf("transferData: WritePipeAsyncFailed, err = %08x\n", err);
528             CFRunLoopRemoveSource(CFRunLoopGetCurrent(), cfSource, kCFRunLoopDefaultMode);
529             return err;
530         }
531         
532         CFRunLoopRun();
533         CFRunLoopRemoveSource(CFRunLoopGetCurrent(), cfSource, kCFRunLoopDefaultMode);
534         return err;
535     }
536     
537     return kIOReturnNoDevice;
538 }
539 
540 IOReturn MyUSBDevice::DeviceRequestSync(UsbHandle *dev, UInt8 cmd, UInt16 deviceAddress, 
541                                             UInt16 length, UInt8 *Buffer)
542 {
543     if (dev->dev) {
544         
545         IOUSBDevRequest        request;
546         request.bmRequestType = USBmakebmRequestType(kUSBOut, kUSBVendor, kUSBDevice);
547         request.bRequest = cmd;
548         request.wValue = deviceAddress;
549         request.wIndex = 0;                //the default control pipe
550         request.wLength = length;
551         request.pData = Buffer;
552         
553         return (*(dev->dev))->DeviceRequestAsync(dev->dev, &request, 
554                 (IOAsyncCallback1)OperationCallBack, (void *)cmd);
555     }
556     
557     return kIOReturnNoDevice;
558 }
559 
560 HANDLE MyUSBDevice::GetDeviceHandle(u32 nIndex)
561 {
562     if (devVector.empty()) {
563         printf("vector empty\n");
564         return NULL;
565     }
566     vector<UsbHandle *>::size_type i;
567     for (i = 0; i < devVector.size(); i++) {
568         UsbHandle *tmp = devVector.at(i);
569         if (tmp->locationID == nIndex) {
570             return (HANDLE)tmp;
571         }
572     }
573     return NULL;
574 }
575 
576 void MyUSBDevice::OperationCallBack(void *refcon, IOReturn result, void *arg0)
577 {
578     if (result == kIOReturnSuccess && refcon) {
579         u32 *pLen = (u32 *)refcon;
580         *pLen = reinterpret_cast<long long>(arg0);
581     }
582 
583     CFRunLoopStop(CFRunLoopGetCurrent());
584 }
585 
586 bool GetDevIndex(PCHAR devName, u32 &nIndex)
587 {
588     if (devName == NULL) {
589         return false;
590     }
591     PCHAR tmp = devName;
592     nIndex = strtoul(tmp, NULL, 16);
593 
594     return true;
595 }
596 
597 //Open USB Device
598 u32 TEST_Open(HANDLE *phDevice, PCHAR devName)
599 {
600     u32 devIndex = 0;
601     kern_return_t                    kr;
602 
603     printf("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
604     if (phDevice == NULL) {
605         return __LINE__;
606     }
607     if (false == GetDevIndex(devName, devIndex)) {
608         printf("GetDevIndex Failed\n");
609         return __LINE__;
610     }
611     
612     MyUSBDevice *pDev = MyUSBDevice::Allocate();
613     kr = pDev->initialize();
614     if(kr != kIOReturnSuccess) {
615         printf("initialize device failed: %08x", kr);
616         return __LINE__;
617     }
618     
619     *phDevice = pDev->GetDeviceHandle(devIndex);
620     
621     return 0;
622 }
623 
624 //Close USB Device
625 u32 TEST_Close(HANDLE *hDevice)
626 {
627     MyUSBDevice *pDev = MyUSBDevice::GetInstance();
628     
629     if (pDev && hDevice && *hDevice) {
630         pDev->Release((MyUSBDevice::UsbHandle *)(*hDevice));
631         return 0;
632     }
633     return __LINE__;
634 }
635 
636 u32 TEST_Query(HANDLE *hDevice, void *pToDriver, u32 ToLen, void *pFromDriver, u32 FromLen, u32 &nRead)
637 {
638     return 0;
639 }
640 
641 #if 0
642 u32 TEST_Send(HANDLE *hDevice, u8 *buffer, u32 Len, u32  &nSend)
643 {
644     MyUSBDevice *pDev = MyUSBDevice::GetInstance();
645     
646     if (pDev && hDevice && *hDevice) {
647         kern_return_t kr;
648 
649         kr = pDev->WriteSync((MyUSBDevice::UsbHandle *)(*hDevice), buffer, Len);
650         if(kr == kIOReturnSuccess) {
651             nSend = Len;
652             return 0;
653         }
654     }
655     return __LINE__;
656 }
657 
658 u32 TEST_Recv(HANDLE *hDevice, u8 *buffer, u32 Len, u32  &nRecv)
659 {
660     MyUSBDevice *pDev = MyUSBDevice::GetInstance();
661     
662     if (pDev && hDevice && *hDevice) {
663         kern_return_t kr;
664         u32 nRead = Len;
665 
666         kr = pDev->ReadSync((MyUSBDevice::UsbHandle *)(*hDevice), buffer, &nRead);
667         if(kr == kIOReturnSuccess) {
668             nRecv = nRead;
669             return 0;
670         }
671 
672         printf("Read Pipe Error %08x\n", kr);
673         return __LINE__;
674     }
675     return __LINE__;
676 }
677 
678 #else
679 u32 TEST_Send(HANDLE *hDevice, u8 *buffer, u32 Len, u32  &nSend)
680 {
681     MyUSBDevice *pDev = MyUSBDevice::GetInstance();
682     
683     if (pDev && hDevice && *hDevice) {
684         u32 nWrite = Len;
685         kern_return_t kr;
686     
687         kr = pDev->WriteAsync((MyUSBDevice::UsbHandle *)(*hDevice), buffer, Len, &nWrite);
688         if (kr == kIOReturnSuccess) {
689             nSend = nWrite;
690             return 0;
691         }
692     }
693     return __LINE__;
694 }
695 
696 u32 TEST_Recv(HANDLE *hDevice, u8 *buffer, u32 Len, u32  &nRecv)
697 {
698     MyUSBDevice *pDev = MyUSBDevice::GetInstance();
699 
700     memset(buffer, 0, Len);
701     
702     if (pDev && hDevice && *hDevice) {
703         u32 nRead = Len;
704         kern_return_t kr;
705         
706         kr = pDev->ReadAsync((MyUSBDevice::UsbHandle *)(*hDevice), buffer, Len, &nRead);
707         if (kr == kIOReturnSuccess) {
708             nRecv = nRead;
709             return 0;
710         }
711     }
712 
713     return __LINE__;
714 }
715 #endif
原文地址:https://www.cnblogs.com/jojodru/p/2715070.html