15#ifndef kIOFireWireAVCLibUnitInterfaceID2
16#define kIOFireWireAVCLibUnitInterfaceID2 \
17 CFUUIDGetConstantUUIDWithBytes( \
19 0x85, 0xB5, 0xE9, 0x54, 0x0A, 0xEF, 0x11, 0xD8, \
20 0x8D, 0x19, 0x00, 0x03, 0x93, 0x91, 0x4A, 0xBA)
24 void* , io_service_t , natural_t messageType,
28 IONotificationPortRef notify_port,
29 CFRunLoopRef &thread_cf_ref, io_object_t obj)
31 IOObjectRelease(fw_device_notifier_ref);
32 IOObjectRelease(fw_node_ref);
33 IOObjectRelease(fw_device_ref);
34 IOObjectRelease(fw_service_ref);
35 IOObjectRelease(avc_service_ref);
37 avc_service_ref = obj;
39 IORegistryEntryGetParentEntry(
40 avc_service_ref, kIOServicePlane, &fw_service_ref);
41 IORegistryEntryGetParentEntry(
42 fw_service_ref, kIOServicePlane, &fw_device_ref);
43 IORegistryEntryGetParentEntry(
44 fw_device_ref, kIOServicePlane, &fw_node_ref);
48 IOServiceAddInterestNotification(
49 notify_port, obj, kIOGeneralInterest,
51 &fw_device_notifier_ref);
62 CFMutableDictionaryRef props;
63 int ret = IORegistryEntryCreateCFProperties(
64 obj, &props, kCFAllocatorDefault, kNilOptions);
65 if (kIOReturnSuccess != ret)
68 auto specDesc = (CFNumberRef)
69 CFDictionaryGetValue(props, CFSTR(
"Unit_Spec_ID"));
70 CFNumberGetValue(specDesc, kCFNumberSInt32Type, &m_specid);
72 auto typeDesc = (CFNumberRef)
73 CFDictionaryGetValue(props, CFSTR(
"Unit_Type"));
74 CFNumberGetValue(typeDesc, kCFNumberSInt32Type, &m_modelid);
76 auto vendorDesc = (CFNumberRef)
77 CFDictionaryGetValue(props, CFSTR(
"Vendor_ID"));
78 CFNumberGetValue(vendorDesc, kCFNumberSInt32Type, &m_vendorid);
80 auto versionDesc = (CFNumberRef)
81 CFDictionaryGetValue(props, CFSTR(
"Unit_SW_Version"));
82 CFNumberGetValue(versionDesc, kCFNumberSInt32Type, &m_firmware_revision);
84 auto tmp0 = (CFStringRef)
85 CFDictionaryGetValue(props, CFSTR(
"FireWire Product Name"));
89 memset(tmp1, 0,
sizeof(tmp1));
90 CFStringGetCString(tmp0, tmp1,
sizeof(tmp1) -
sizeof(
char),
91 kCFStringEncodingMacRoman);
92 m_product_name = QString(
"%1").arg(tmp1);
100 LOG(VB_RECORD, LOG_INFO, QString(
"Scanning guid: 0x%1").arg(m_guid, 0, 16));
102 bool wasOpen = IsAVCInterfaceOpen();
103 if (OpenAVCInterface(thread_cf_ref))
105 if (!GetSubunitInfo())
107 LOG(VB_GENERAL, LOG_ERR,
"GetSubunitInfo failed");
115bool DarwinAVCInfo::SendAVCCommand(
116 const std::vector<uint8_t> &cmd,
117 std::vector<uint8_t> &result,
122 uint32_t result_length = 4096;
123 uint8_t response[4096];
128 int ret = (*avc_handle)->
129 AVCCommand(avc_handle, (
const UInt8*) &cmd[0], cmd.size(),
130 response, (UInt32*) &result_length);
132 if (ret != kIOReturnSuccess)
136 result.insert(result.end(), response, response + result_length);
141bool DarwinAVCInfo::OpenPort(CFRunLoopRef &thread_cf_ref)
146 if (!OpenAVCInterface(thread_cf_ref))
149 if (!OpenDeviceInterface(thread_cf_ref))
158bool DarwinAVCInfo::ClosePort(
void)
160 CloseDeviceInterface();
165bool DarwinAVCInfo::OpenAVCInterface(CFRunLoopRef &thread_cf_ref)
167 if (IsAVCInterfaceOpen())
170 if (!avc_service_ref)
173 IOCFPlugInInterface **input_plug;
175 int ret = IOCreatePlugInInterfaceForService(
176 avc_service_ref, kIOFireWireAVCLibUnitTypeID, kIOCFPlugInInterfaceID,
177 &input_plug, (SInt32*) &dummy);
179 if (kIOReturnSuccess != ret)
183 HRESULT err = (*input_plug)->QueryInterface(
185 (
void**) &avc_handle);
190 err = (*input_plug)->QueryInterface(
191 input_plug, CFUUIDGetUUIDBytes(kIOFireWireAVCLibUnitInterfaceID),
192 (
void**) &avc_handle);
197 (*input_plug)->Release(input_plug);
202 ret = (*avc_handle)->addCallbackDispatcherToRunLoop(
203 avc_handle, thread_cf_ref);
205 (*input_plug)->Release(input_plug);
207 if (kIOReturnSuccess != ret)
209 (*avc_handle)->Release(avc_handle);
210 avc_handle =
nullptr;
214 ret = (*avc_handle)->open(avc_handle);
215 if (kIOReturnSuccess != ret)
217 (*avc_handle)->Release(avc_handle);
218 avc_handle =
nullptr;
225void DarwinAVCInfo::CloseAVCInterface(
void)
230 (*avc_handle)->removeCallbackDispatcherFromRunLoop(avc_handle);
231 (*avc_handle)->close(avc_handle);
232 (*avc_handle)->Release(avc_handle);
234 avc_handle =
nullptr;
237bool DarwinAVCInfo::OpenDeviceInterface(CFRunLoopRef &thread_cf_ref)
245 IOCFPlugInInterface **input_plug;
247 int ret = IOCreatePlugInInterfaceForService(
248 fw_device_ref, kIOFireWireLibTypeID, kIOCFPlugInInterfaceID,
249 &input_plug, (SInt32*) &dummy);
251 if (kIOReturnSuccess != ret)
254 HRESULT err = (*input_plug)->QueryInterface(
255 input_plug, CFUUIDGetUUIDBytes(kIOFireWireNubInterfaceID),
256 (
void**) &fw_handle);
260 (*input_plug)->Release(input_plug);
265 ret = (*fw_handle)->AddCallbackDispatcherToRunLoop(
266 fw_handle, thread_cf_ref);
268 (*input_plug)->Release(input_plug);
270 if (kIOReturnSuccess == ret)
273 ret = (*fw_handle)->OpenWithSessionRef(
274 fw_handle, (*avc_handle)->getSessionRef(avc_handle));
277 if (kIOReturnSuccess != ret)
279 (*fw_handle)->Release(fw_handle);
287void DarwinAVCInfo::CloseDeviceInterface(
void)
292 (*fw_handle)->RemoveCallbackDispatcherFromRunLoop(fw_handle);
293 (*fw_handle)->Close(fw_handle);
294 (*fw_handle)->Release(fw_handle);
299bool DarwinAVCInfo::GetDeviceNodes(
int &local_node,
int &remote_node)
301 uint32_t generation = 0;
306 if ((*fw_handle)->version < 4)
308 if (kIOReturnSuccess == (*fw_handle)->GetGenerationAndNodeID(
309 fw_handle, (UInt32*) &generation, (UInt16*) &node))
314 if (kIOReturnSuccess == (*fw_handle)->GetLocalNodeID(
315 fw_handle, (UInt16*) &node))
321 int ret = (*fw_handle)->GetBusGeneration(fw_handle, (UInt32*)&generation);
322 if (kIOReturnSuccess == ret)
324 if (kIOReturnSuccess == (*fw_handle)->GetLocalNodeIDWithGeneration(
325 fw_handle, generation, (UInt16*) &node))
330 if (kIOReturnSuccess == (*fw_handle)->GetRemoteNodeID(
331 fw_handle, generation, (UInt16*) &node))
337 return (local_node >= 0) && (remote_node >= 0);
341 void *dfd, io_service_t , natural_t messageType,
void* )
void HandleDeviceChange(uint messageType)
static void dfd_device_change_msg(void *, io_service_t, natural_t messageType, void *)
#define kIOFireWireAVCLibUnitInterfaceID2
DarwinFirewireChannel Copyright (c) 2006 by Daniel Kristjansson Distributed as part of MythTV under G...
#define LOG(_MASK_, _LEVEL_, _QSTRING_)