Replying to my own post...
It was my own mistake.
<key>com.apple.security.temporary-exception.iokit-user-client-class</key>
<array>
<string>IOUserUserClient</string>
</array>
The above entitlement does work. Now we just need to figure out whether USBDriverkit (dext) + camera extension (CMIOExtension) is the right approach.
Post
Replies
Boosts
Views
Activity
In USBDriverKit.framework/Headers/AppleUSBDefinitions.h
enum tIOUSBDeviceRequest
{
kIOUSBDeviceRequestSize = 8,
kIOUSBDeviceRequestDirectionMask = IOUSBBit(7),
kIOUSBDeviceRequestDirectionPhase = IOUSBBitRangePhase(7, 7),
kIOUSBDeviceRequestDirectionOut = (kIOUSBDeviceRequestDirectionValueOut << kIOUSBDeviceRequestDirectionPhase),
kIOUSBDeviceRequestDirectionIn = (kIOUSBDeviceRequestDirectionValueIn << kIOUSBDeviceRequestDirectionPhase),
kIOUSBDeviceRequestTypeMask = IOUSBBitRange(5, 6),
kIOUSBDeviceRequestTypePhase = IOUSBBitRangePhase(5, 6),
kIOUSBDeviceRequestTypeStandard = (kIOUSBDeviceRequestTypeValueStandard << kIOUSBDeviceRequestTypePhase),
kIOUSBDeviceRequestTypeClass = (kIOUSBDeviceRequestTypeValueClass << kIOUSBDeviceRequestTypePhase),
kIOUSBDeviceRequestTypeVendor = (kIOUSBDeviceRequestTypeValueVendor << kIOUSBDeviceRequestTypePhase),
kIOUSBDeviceRequestRecipientMask = IOUSBBitRange(0, 4),
kIOUSBDeviceRequestRecipientPhase = IOUSBBitRangePhase(0, 4),
kIOUSBDeviceRequestRecipientDevice = (kIOUSBDeviceRequestRecipientValueDevice << kIOUSBDeviceRequestRecipientPhase),
kIOUSBDeviceRequestRecipientInterface = (kIOUSBDeviceRequestRecipientValueInterface << kIOUSBDeviceRequestRecipientPhase),
kIOUSBDeviceRequestRecipientEndpoint = (kIOUSBDeviceRequestRecipientValueEndpoint << kIOUSBDeviceRequestRecipientPhase),
kIOUSBDeviceRequestRecipientOther = (kIOUSBDeviceRequestRecipientValueOther << kIOUSBDeviceRequestRecipientPhase),
};
should be what you are looking for.
I am on macOS 13.2 with Xcode 14.2.
I was unable to get the custom property CMIOExtensionPropertyState of type NSDictionary and NSArray. (I was able to get values and sizes for type NSNumber, NSString, NSData).
the code failed on trying to determining the PropertyDataSize
CMIO_DAL_CMIOExtension_Device.mm:901:GetPropertyDataSize 46 wrong 4cc format for key 4cc_just_glob_0000 value {object1 = someValue;}
CMIO_DAL_CMIOExtension_Device.mm:906:GetPropertyDataSize unknown property error just
CMIOHardware.cpp:260:CMIOObjectGetPropertyDataSize Error: 2003332927, failed //('who?') kCMIOHardwareUnknownPropertyError
In CMIOExtensionDeviceSource...
const CMIOExtensionProperty CMIOExtensionPropertyCustomPropertyData_just = @"4cc_just_glob_0000";
- (NSSet<CMIOExtensionProperty> *)availableProperties
{
return [NSSet setWithObjects:
CMIOExtensionPropertyDeviceTransportType,
CMIOExtensionPropertyDeviceModel,
CMIOExtensionPropertyCustomPropertyData_just,
nil];
}
- (nullable CMIOExtensionDeviceProperties *)devicePropertiesForProperties:(NSSet<CMIOExtensionProperty> *)properties error:(NSError * _Nullable *)outError
{
CMIOExtensionDeviceProperties *deviceProperties = [CMIOExtensionDeviceProperties devicePropertiesWithDictionary:@{}];
if ([properties containsObject:CMIOExtensionPropertyDeviceTransportType]) {
deviceProperties.transportType = [NSNumber numberWithInt:kIOAudioDeviceTransportTypeVirtual];
}
if ([properties containsObject:CMIOExtensionPropertyDeviceModel]) {
deviceProperties.model = @"SampleCapture Model";
}
if ([properties containsObject:CMIOExtensionPropertyCustomPropertyData_just]) {
NSDictionary *numberDictionary = [[NSDictionary alloc] initWithObjectsAndKeys: @"someValue", @"object1", nil];
CMIOExtensionPropertyState* propertyState = [CMIOExtensionPropertyState propertyStateWithValue: numberDictionary];
//NSArray *numberArray = [[NSArray alloc] initWithObjects:@"a", @"b", @"c", @"d", nil];
//CMIOExtensionPropertyState* propertyState = [CMIOExtensionPropertyState propertyStateWithValue: numberArray];
[deviceProperties setPropertyState:propertyState forProperty:CMIOExtensionPropertyCustomPropertyData_just];
}
return deviceProperties;
}
In CMIO APIs
CMIOObjectPropertyAddress propertyAddress = {
(FOUR_CHAR_CODE( 'just' )),
(kCMIOObjectPropertyScopeGlobal),
(kCMIOObjectPropertyElementMain)
};
UInt32 dataSize = 0 ;
UInt32 dataUsed = 0 ;
OSStatus status = 0;
status = CMIOObjectGetPropertyDataSize(deviceID, &propertyAddress, 0 , nil , &dataSize);
...
//CFNumberRef value = NULL;
//CFStringRef value = NULL ;
//UInt8 value[16] = {0};
status = CMIOObjectGetPropertyData(deviceID, &propertyAddress, 0 , nil , dataSize, &dataUsed, &value);
Has anyone encountered similar situation?
@ssmith_c @DrXibber I appreciate the replies. I ran into another situation while experimenting custom props.
Is there ways to obtain a property's min and max from CMIOExtensionPropertyAttributes if a property is declared as
- (nullable CMIOExtensionDeviceProperties *)devicePropertiesForProperties:(NSSet<CMIOExtensionProperty> *)properties error:(NSError * _Nullable *)outError
{
CMIOExtensionDeviceProperties *deviceProperties = [CMIOExtensionDeviceProperties devicePropertiesWithDictionary:@{}];
if ([properties containsObject:CMIOExtensionPropertyCustomPropertyData_just]) {
NSNumber *min = [[NSNumber alloc] initWithInt:0];
NSNumber *max = [[NSNumber alloc] initWithInt:5];
NSNumber *val = [[NSNumber alloc] initWithInt:3];
NSArray *validRange = @[@0,@1,@2,@3,@4,@5];
CMIOExtensionPropertyAttributes *propertyAttirbutes =
[CMIOExtensionPropertyAttributes propertyAttributesWithMinValue: min maxValue: max validValues: validRange readOnly:NO];
CMIOExtensionPropertyState* propertyState = [CMIOExtensionPropertyState propertyStateWithValue:val attributes:propertyAttirbutes];
[deviceProperties setPropertyState:propertyState forProperty:CMIOExtensionPropertyCustomPropertyData_just];
}
return deviceProperties;
}
In the CMIO API I was able to get the read only boolean value by calling
CMIOObjectPropertyAddress propertyAddress = {
(FOUR_CHAR_CODE( 'just' )),
(kCMIOObjectPropertyScopeGlobal),
(kCMIOObjectPropertyElementMain)};
Boolean settable;
status = CMIOObjectIsPropertySettable(deviceID, &propertyAddress, &settable);
However, calling things like (how we obtained property range for legacy CoreMediaIO plugin)
AudioValueRange myRange;
CMIOObjectPropertyAddress opa = {kCMIOFeatureControlPropertyAbsoluteValue, kCMIOObjectPropertyScopeGlobal, kCMIOObjectPropertyElementMain};
CMIOObjectPropertyAddress opa = {kCMIOFeatureControlPropertyNativeRange, kCMIOObjectPropertyScopeGlobal, kCMIOObjectPropertyElementMain};
result = CMIOObjectGetPropertyDataSize(deivceID, &opa, 0, NULL, &dataSize);
result = CMIOObjectGetPropertyData(deivceID, &opa, 0, NULL, dataSize, &dataSize, &myRange);
did not work and returned
Error: 2003332927, failed //('who?') kCMIOHardwareUnknownPropertyError
Does anyone know the how to obtain values in CMIOExtensionPropertyAttributes?
@DrXibber I tried sending out of range value to the property. The min/max boundary didn't seem to have effect.
Calling
status = CMIOObjectSetPropertyData(devices[i], &propertyAddress, 0, nil, dataSize, &value)
with an out of range value will still trigger
- (BOOL)setDeviceProperties:(CMIOExtensionDeviceProperties *)deviceProperties error:(NSError * _Nullable *)outError
in CMIOExtension. you can then manipulate the data with own internal logics.
However, the value in readOnly attribute in CMIOExtensionPropertyAttributes will be correctly reflected on corresponding CMIO APIs
...
Boolean settable;
status = CMIOObjectIsPropertySettable(deviceID, &propertyAddress, &settable);
status = CMIOObjectSetPropertyData(devices[i], &propertyAddress, 0, nil, dataSize, &value);