zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    loj#2020. 「AHOI / HNOI2017」礼物
    loj#117. 有源汇有上下界最小流
    loj#6491. zrq 学反演
    loj#6261. 一个人的高三楼
    loj#528. 「LibreOJ β Round #4」求和
    2018-2019 ACM-ICPC Brazil Subregional Programming Contest
    2015-2016 ACM-ICPC, NEERC, Moscow Subregional Contest J
    2015-2016 ACM-ICPC Northeastern European Regional Contest (NEERC 15)C
    addEventListener() 和 removeEventListener()
    9个图片滑块动画
  • 原文地址:https://www.cnblogs.com/jojodru/p/2715070.html
Copyright © 2011-2022 走看看