int uvccGetCamList(uvccCam ***list) { CFDictionaryRef mRef; io_iterator_t devIter; kern_return_t kr; int nCams; /* make sure we've been initialized */ if(!uvcc_port) { fprintf(stderr, UVCC_INIT_ERROR_MSG); return -1; } /* get the matching dic, get_usb_service_dic dumps error if needed */ if(!(mRef = get_usb_service_dic())) return -1; /* get ALL the cams! */ kr = IOServiceGetMatchingServices(uvcc_port, mRef, &devIter); if(kr != kIOReturnSuccess || !IOIteratorIsValid(devIter)) { uvcc_err("uvccGetCamList: IOServiceGetMatchingServices", kr); return -1; } /* normally one ref of mdRef should be consumed by IOServiceGet... but a bug in os x < Tiger can cause that to be missed. unfortunately you can't get the retain count on a completely released obj in a safe manor since they may or may not be free'd. if(CFGetRetainCount(mRef) > 0) CFRelease(mRef); */ nCams = get_cam_list(devIter, list); IOObjectRelease(devIter); return nCams; }
/* * Initializes the haptic subsystem. */ int SDL_SYS_HapticInit(void) { IOReturn result; io_iterator_t iter; CFDictionaryRef match; io_service_t device; if (numhaptics != -1) { return SDL_SetError("Haptic subsystem already initialized!"); } numhaptics = 0; /* Get HID devices. */ match = IOServiceMatching(kIOHIDDeviceKey); if (match == NULL) { return SDL_SetError("Haptic: Failed to get IOServiceMatching."); } /* Now search I/O Registry for matching devices. */ result = IOServiceGetMatchingServices(kIOMasterPortDefault, match, &iter); if (result != kIOReturnSuccess) { return SDL_SetError("Haptic: Couldn't create a HID object iterator."); } /* IOServiceGetMatchingServices consumes dictionary. */ if (!IOIteratorIsValid(iter)) { /* No iterator. */ return 0; } while ((device = IOIteratorNext(iter)) != IO_OBJECT_NULL) { MacHaptic_MaybeAddDevice(device); /* always release as the AddDevice will retain IF it's a forcefeedback device */ IOObjectRelease(device); } IOObjectRelease(iter); return numhaptics; }
static int FindHIDDevices(mach_port_t masterPort, io_iterator_t *hidObjectIterator) { CFMutableDictionaryRef hidMatchDictionary; IOReturn ioReturnValue; // Set up a matching dictionary to search the I/O Registry // by class name for all HID class devices. hidMatchDictionary = IOServiceMatching("AppleIRController"); // Now search I/O Registry for matching devices. ioReturnValue = IOServiceGetMatchingServices(masterPort, hidMatchDictionary, hidObjectIterator); // If search is unsuccessful, print message and hang. if (ioReturnValue != kIOReturnSuccess || !IOIteratorIsValid(*hidObjectIterator)) { return -1; } return 0; }
/** Initializes the USB system. Returns 0 on success, -1 on error. */ static int init_usb(ifc_match_func callback, std::unique_ptr<usb_handle>* handle) { int ret = -1; CFMutableDictionaryRef matchingDict; kern_return_t result; io_iterator_t iterator; usb_handle h; h.success = 0; h.callback = callback; /* * Create our matching dictionary to find appropriate devices. * IOServiceAddMatchingNotification consumes the reference, so we * do not need to release it. */ matchingDict = IOServiceMatching(kIOUSBDeviceClassName); if (matchingDict == NULL) { ERR("Couldn't create USB matching dictionary.\n"); return -1; } result = IOServiceGetMatchingServices( kIOMasterPortDefault, matchingDict, &iterator); if (result != 0) { ERR("Could not create iterator."); return -1; } for (;;) { if (! IOIteratorIsValid(iterator)) { /* * Apple documentation advises resetting the iterator if * it should become invalid during iteration. */ IOIteratorReset(iterator); continue; } io_service_t device = IOIteratorNext(iterator); if (device == 0) { break; } if (try_device(device, &h) != 0) { IOObjectRelease(device); continue; } if (h.success) { handle->reset(new usb_handle); memcpy(handle->get(), &h, sizeof(usb_handle)); ret = 0; break; } IOObjectRelease(device); } IOObjectRelease(iterator); return ret; }
bool TMSerialPort::HasValidIterator() { return (serialPortIterator != 0) && IOIteratorIsValid(serialPortIterator); }
/* * Initializes the haptic subsystem. */ int SDL_SYS_HapticInit(void) { int numhaptics; IOReturn result; io_iterator_t iter; CFDictionaryRef match; io_service_t device; CFMutableDictionaryRef hidProperties; CFTypeRef refCF; /* Clear all the memory. */ SDL_memset(SDL_hapticlist, 0, sizeof(SDL_hapticlist)); /* Get HID devices. */ match = IOServiceMatching(kIOHIDDeviceKey); if (match == NULL) { return SDL_SetError("Haptic: Failed to get IOServiceMatching."); } /* Now search I/O Registry for matching devices. */ result = IOServiceGetMatchingServices(kIOMasterPortDefault, match, &iter); if (result != kIOReturnSuccess) { return SDL_SetError("Haptic: Couldn't create a HID object iterator."); } /* IOServiceGetMatchingServices consumes dictionary. */ if (!IOIteratorIsValid(iter)) { /* No iterator. */ return 0; } numhaptics = 0; while ((device = IOIteratorNext(iter)) != IO_OBJECT_NULL) { /* Check for force feedback. */ if (FFIsForceFeedback(device) == FF_OK) { /* Set basic device data. */ HIDGetDeviceProduct(device, SDL_hapticlist[numhaptics].name); SDL_hapticlist[numhaptics].dev = device; SDL_hapticlist[numhaptics].haptic = NULL; /* Set usage pages. */ hidProperties = 0; refCF = 0; result = IORegistryEntryCreateCFProperties(device, &hidProperties, kCFAllocatorDefault, kNilOptions); if ((result == KERN_SUCCESS) && hidProperties) { refCF = CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDPrimaryUsagePageKey)); if (refCF) { if (!CFNumberGetValue(refCF, kCFNumberLongType, &SDL_hapticlist[numhaptics]. usagePage)) SDL_SetError ("Haptic: Recieving device's usage page."); refCF = CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDPrimaryUsageKey)); if (refCF) { if (!CFNumberGetValue(refCF, kCFNumberLongType, &SDL_hapticlist[numhaptics]. usage)) SDL_SetError("Haptic: Recieving device's usage."); } } CFRelease(hidProperties); } /* Device has been added. */ numhaptics++; } else { /* Free the unused device. */ IOObjectRelease(device); } /* Reached haptic limit. */ if (numhaptics >= MAX_HAPTICS) break; } IOObjectRelease(iter); return numhaptics; }
/* this is where most of the getting magic happens.. */ static int get_cam_list(io_iterator_t devIter, uvccCam ***list) { io_iterator_t ifIter; kern_return_t kr; int i, nDevs = 0, nCams = 0; uvccCam **tmp; io_service_t devSrv, ifSrv; /* unsigned int */ IOCFPlugInInterface **pIf; /* needed to find the device interface */ HRESULT qiRes; /* int32_t */ int32_t score; IOUSBDeviceInterface197 **devIf; /* interface to communicate with the device */ if(!uvcc_port) { fprintf(stderr, UVCC_INIT_ERROR_MSG); return -1; } /* get number of devices */ while((IOIteratorNext(devIter)) != 0) nDevs++; if(!nDevs) return 0; IOIteratorReset(devIter); tmp = malloc(nDevs*sizeof(uvccCam *)); while((devSrv = IOIteratorNext(devIter))) { kr = IOCreatePlugInInterfaceForService(devSrv, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &pIf, &score); /* we're done with the devSrv */ IOObjectRelease(devSrv); if(kr != kIOReturnSuccess) { uvcc_err("get_cam_list: IOCreatePlugInInterfaceForService", kr); IOObjectRelease(devSrv); continue; } qiRes = (*pIf)->QueryInterface(pIf, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID197), (LPVOID)&devIf); /* we're done with the plugin */ (*pIf)->Stop(pIf); IODestroyPlugInInterface(pIf); /* kIOReturnSuccess is actually just 0 but since QI strictly talking returns HRESULT (int32_t) and not kern_return_t (int) i figured i'll just do this here */ if(!qiRes && devIf) { kr = (*devIf)->CreateInterfaceIterator(devIf, &vid_ctrl_if_req, &ifIter); if(kr != kIOReturnSuccess || !IOIteratorIsValid(ifIter)) { uvcc_err("get_cam_list: CreateInterfaceIterator", kr); IOObjectRelease(devSrv); continue; } if((ifSrv = IOIteratorNext(ifIter))) { /* we'll just use the first vid ctrl if we get */ if((tmp[nCams] = malloc(sizeof(uvccCam))) == NULL) { if(!logger) perror("uvcc error! get_cam_list: Could not allocate memory for list entry"); else asl_log(logger, NULL, ASL_LEVEL_ERR, "get_cam_list: Could not allocate memory for list entry: %s", strerror(errno)); IOObjectRelease(ifIter); (*devIf)->Release(devIf); IOObjectRelease(devSrv); break; } /* set the data.. */ if((fill_cam_struct(devIf, tmp[nCams])) != 0) { (*devIf)->Release(devIf); IOObjectRelease(devSrv); continue; } /* get the registry name */ set_cam_reg_name(devSrv, tmp[nCams]); nCams++; IOObjectRelease(ifSrv); } /* else: no vid_ctrl_iface, i.e. not cam */ IOObjectRelease(ifIter); } else { if(!logger) perror("uvcc warning! get_cam_list: QueryInterface failed"); else asl_log(logger, NULL, ASL_LEVEL_WARNING, "get_cam_list: QueryInterface failed: %s", strerror(errno)); } IOObjectRelease(devSrv); } if(nCams > 0) { /* only make the allocation if we got cams */ (*list) = malloc(nCams*sizeof(uvccCam *)); for(i = 0; i < nCams; i++) (*list)[i] = tmp[i]; } free(tmp); return nCams; }
int uvccGetCamsWithModelID(struct uvccModelID *mID, uvccCam ***list) { CFDictionaryRef mRef; CFMutableDictionaryRef mdRef; CFNumberRef nRef; kern_return_t kr; io_iterator_t devIter; int nCams; if(!uvcc_port) { fprintf(stderr, UVCC_INIT_ERROR_MSG); return -1; } if(!(mRef = get_usb_service_dic())) return -1; /* set up the matching criteria for the device service we want */ mdRef = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, mRef); CFRelease(mRef); if(!mdRef) { if(!logger) perror("uvcc error! uvccGetCamsWithModelId: CFDictionaryCreateMutableCopy returned NULL, could not create mutable dictionary."); else asl_log(logger, NULL, ASL_LEVEL_ERR, "uvccGetCamsWithModelId: CFDictionaryCreateMutableCopy returned NULL, could not create mutable dictionary."); return -1; } /* set required fields */ nRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt16Type, &(mID->idVendor)); CFDictionarySetValue(mdRef, CFSTR(kUSBVendorID), nRef); CFRelease(nRef); nRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt16Type, &(mID->idProduct)); CFDictionarySetValue(mdRef, CFSTR(kUSBProductID), nRef); CFRelease(nRef); /* get the actual services */ kr = IOServiceGetMatchingServices(uvcc_port, mdRef, &devIter); /*if(CFGetRetainCount(mdRef) > 0) CFRelease(mdRef);*/ if(kr != kIOReturnSuccess || !IOIteratorIsValid(devIter)) { uvcc_err("uvccGetCamsWithModelID: IOServiceGetMatchingServices", kr); return -1; } nCams = get_cam_list(devIter, list); IOObjectRelease(devIter); return nCams; /* this is just gettting the first one! CFNumberRef nRef; io_iterator_t devIter; io_service_t camSrv; IOUSBDeviceInterface197 **devIf; IOCFPlugInInterface **pIf; kern_return_t kr; int32_t score; HRESULT qiRes; CFDictionaryRef mRef; CFMutableDictionaryRef mdRef; ... * get the actual service * camSrv = IOServiceGetMatchingServices(uvcc_port, mdRef, &devIter); CFRelease(mdRef); * and these darn plugin interfaces * pIfKr = IOCreatePlugInInterfaceForService(camSrv, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &pIf, &score); if(pIfKr != kIOReturnSuccess || !pIf) { uvcc_err("uvccGetCamWithModelId: IOCreatePlugInInterfaceForService", pIfKr); return -1; } qiRes = (*pIf)->QueryInterface(pIf, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (LPVOID *)&devIf); IODestroyPlugInInterface(pIf); if(qiRes || !devIf) { if(!logger) perror("uvcc error! uvccGetCamWithModelId: QueryInterface failed"); else asl_log(logger, NULL, ASL_LEVEL_ERR, "uvccGetCamWithModelId: QueryInterface failed: %s", strerror(errno)); return -1; } * fill and return * if((fill_cam_struct(devIf, cam)) != 0) { (*devIf)->Release(devIf); return -1; } * get the registry name * set_cam_reg_name(camSrv, cam); IOObjectRelease(camSrv); return 0; */ }