DVControlComponent.c [plain text]
#include <Carbon/Carbon.h>
#include "DeviceControlPriv.h"
#include "IsochronousDataHandler.h"
#include "DVVers.h"
#include <stdio.h>
#include <stdlib.h>
#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/IOKitLib.h>
#include <IOKit/avc/IOFireWireAVCLib.h>
#define DEBUG 0
typedef struct ControlComponentInstance ControlComponentInstance, *ControlComponentInstancePtr;
struct ControlComponentInstance
{
ComponentInstance self;
Boolean fDeviceEnable;
IOFireWireAVCLibUnitInterface **fAVCInterface;
};
#define CALLCOMPONENT_BASENAME() IDHDV
#define CALLCOMPONENT_GLOBALS() ControlComponentInstancePtr storage
#define DEVICECONTROL_BASENAME() FWDVC
#define DEVICECONTROL_GLOBALS() ControlComponentInstancePtr storage
#include "DeviceControl.k.h"
#include "DeviceControlPriv.k.h"
pascal ComponentResult
FWDVCCodecComponentDispatch(ComponentParameters *params, char ** storage);
#ifdef DEBUG
#define FailMessage(cond) assert (!(cond))
#else
#define FailMessage(cond) {}
#endif
#define FailWithVal(cond, handler,num) \
if (cond) { \
goto handler; \
}
#define FailWithAction(cond, action, handler) \
if (cond) { \
{ action; } \
goto handler; \
}
#define FailIf(cond, handler) \
if (cond) { \
FailMessage(false); \
goto handler; \
}
#if DEBUG
static void print4(UInt32 val)
{
char a, b, c, d;
a = val>>24;
b = val>>16;
c = val>>8;
d = val;
if(a >= ' ' && b >= ' ' && c >= ' ' && d >= ' ')
printf("%c%c%c%c", a, b, c, d);
else
printf(" 0x%x ", (int)val);
}
static void RecordEventLogger(UInt32 a, UInt32 b, UInt32 c, UInt32 d)
{
if(a)
print4(a);
if(b)
print4(b);
if(c)
print4(c);
if(d)
print4(d);
printf("\n");
}
#else
#define RecordEventLogger(a, b, c, d)
#endif
static pascal ComponentResult
FWDVCDeviceControlDoAVCTransaction(ControlComponentInstancePtr dc,
DVCTransactionParams* inTransaction)
{
if ( dc->fAVCInterface == NULL )
return(kIDHErrInvalidDeviceID);
if ( !dc->fDeviceEnable )
return(kIDHErrDeviceDisconnected);
return (*dc->fAVCInterface)->AVCCommand(dc->fAVCInterface,
inTransaction->commandBufferPtr, inTransaction->commandLength,
inTransaction->responseBufferPtr, &inTransaction->responseBufferSize);
}
static pascal ComponentResult
FWDVCDeviceControlEnableAVCTransactions(ControlComponentInstancePtr dc)
{
ComponentResult result = noErr;
if ( dc->fAVCInterface != NULL )
dc->fDeviceEnable = true;
else
result = kIDHErrDeviceNotOpened;
return result;
}
static pascal ComponentResult
FWDVCDeviceControlDisableAVCTransactions(ControlComponentInstancePtr dc)
{
ComponentResult result = noErr;
dc->fDeviceEnable = false;
return result;
}
static pascal ComponentResult
FWDVCDeviceControlSetDeviceConnectionID(
ControlComponentInstancePtr dc, DeviceConnectionID connectionID)
{
ComponentResult result = noErr;
if ( dc->fDeviceEnable )
result = kIDHErrDeviceInUse;
else {
if(dc->fAVCInterface != NULL)
(*dc->fAVCInterface)->Release(dc->fAVCInterface);
dc->fAVCInterface = (IOFireWireAVCLibUnitInterface **)(connectionID);
if(dc->fAVCInterface != NULL)
(*dc->fAVCInterface)->AddRef(dc->fAVCInterface);
}
return result;
}
static pascal ComponentResult
FWDVCDeviceControlGetDeviceConnectionID(
ControlComponentInstancePtr dc, DeviceConnectionID* connectionID)
{
*connectionID = (DeviceConnectionID)dc->fAVCInterface;
return noErr;
}
static pascal ComponentResult
FWDVCComponentOpen(ControlComponentInstancePtr storage, ComponentInstance self)
{
kern_return_t err = noErr;
RecordEventLogger( 'devc', 'open', 0, 0);
storage = (ControlComponentInstancePtr)NewPtrClear(sizeof(ControlComponentInstance));
if( nil == storage)
return(MemError());
RecordEventLogger( 'devc', 'ope2', (int)storage, 0);
SetComponentInstanceStorage(self, (Handle) storage);
return( err );
}
static pascal ComponentResult
FWDVCComponentClose(ControlComponentInstancePtr storage, ComponentInstance self)
{
RecordEventLogger( 'devc', 'clos', 0, (unsigned long) storage);
if( !storage)
return( noErr );
if(storage->fAVCInterface != NULL)
(*storage->fAVCInterface)->Release(storage->fAVCInterface);
DisposePtr((Ptr) storage);
SetComponentInstanceStorage(self, (Handle) nil );
return( noErr );
}
static pascal ComponentResult
FWDVCComponentVersion(ControlComponentInstancePtr storage)
{
RecordEventLogger( 'devc', 'vers', 0, 0);
return 0x10001;
}
static pascal ComponentResult
FWDVCComponentRegister(ControlComponentInstancePtr storage)
{
RecordEventLogger( 'devc', 'reg ', 0, 0);
return( noErr );
}
#define DoCDispatchWS(x,p,s) \
case k ## x ## Select: \
\
{ ComponentResult err; \
err = CallComponentFunctionWithStorageProcInfo( s, p, (ProcPtr) FWDVC ## x, \
uppCall ## x ## ProcInfo ); \
\
return err; }
#define DoDispatchWS(x,p,s) \
case k ## x ## Select: \
\
{ ComponentResult err; \
err = CallComponentFunctionWithStorageProcInfo( s, p, (ProcPtr) FWDVC ## x, \
upp ## x ## ProcInfo ); \
\
return err; }
static pascal ComponentResult
FWDVCComponentCanDo(ControlComponentInstancePtr storage, short selector)
{
RecordEventLogger( 'devc', 'cand', 0, 0);
switch(selector) {
case kComponentOpenSelect:
case kComponentCloseSelect:
case kComponentCanDoSelect:
case kComponentVersionSelect:
case kDeviceControlDoAVCTransactionSelect:
case kDeviceControlEnableAVCTransactionsSelect:
case kDeviceControlDisableAVCTransactionsSelect:
case kDeviceControlSetDeviceConnectionIDSelect:
case kDeviceControlGetDeviceConnectionIDSelect:
return(true);
default:
RecordEventLogger( 'devc', 'cant', selector, 0);
return (false);
}
}
pascal ComponentResult
FWDVCCodecComponentDispatch(ComponentParameters *params, char ** storage)
{
ComponentResult result;
if ( params->what < 0 ) {
switch ( params->what ) {
DoCDispatchWS( ComponentOpen, params, storage );
DoCDispatchWS( ComponentClose, params, storage );
DoCDispatchWS( ComponentRegister, params, storage );
DoCDispatchWS( ComponentCanDo, params, storage );
DoCDispatchWS( ComponentVersion, params, storage );
default :
return (paramErr);
}
}
switch ( params->what ) {
DoDispatchWS( DeviceControlDoAVCTransaction, params, storage );
DoDispatchWS( DeviceControlEnableAVCTransactions, params, storage );
DoDispatchWS( DeviceControlDisableAVCTransactions, params, storage );
DoDispatchWS( DeviceControlSetDeviceConnectionID, params, storage );
DoDispatchWS( DeviceControlGetDeviceConnectionID, params, storage );
default:
{
int len = params->paramSize/4;
int i;
printf("DVC unimp:%d %d ", params->what, params->paramSize);
for(i=0; i<len; i++)
printf("0x%lx ", params->params[i]);
printf("\n");
result = paramErr;
return(result);
}
}
}