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