#include "IrDAUser.h"
#include "AppleIrDA.h"
#include "IrDAComm.h"
#include "IrDALog.h"
#include "IrDADebugging.h"
#define super IOUserClient
#undef ELG
#define ELG(x,y,z,msg) ((void)0)
OSDefineMetaClassAndStructors(IrDAUserClient, IOUserClient)
IrDAUserClient*
IrDAUserClient::withTask(task_t owningTask)
{
IrDAUserClient *client;
ELG(0, owningTask, 'irda', "IrDAUser: withTask");
client = new IrDAUserClient;
if (client != NULL) {
if (client->init() == false) {
client->release();
client = NULL;
}
}
if (client != NULL) {
client->fTask = owningTask;
}
return (client);
}
bool
IrDAUserClient::start(IOService *provider)
{
bool result = false;
ELG(0, 0, 'irda', "IrDAUser: start");
fDriver = OSDynamicCast(AppleIrDASerial, provider);
if (fDriver != NULL)
result = super::start(provider);
else
result = false;
if (result == false) {
IOLog("IrDAUserClient: provider start failed\n");
}
else {
fMethods[0].object = this;
fMethods[0].func = (IOMethod) &IrDAUserClient::userPostCommand;
fMethods[0].count0 = 0xFFFFFFFF;
fMethods[0].count1 = 0xFFFFFFFF;
fMethods[0].flags = kIOUCStructIStructO;
}
return (result);
}
IOReturn
IrDAUserClient::clientClose(void)
{
ELG(0, 0, 'irda', "IrDAUser: client close");
detach(fDriver);
return (kIOReturnSuccess);
}
IOReturn
IrDAUserClient::clientDied(void)
{
ELG(0, 0, 'irda', "IrDAUser: client died");
return (clientClose());
}
IOReturn
IrDAUserClient::connectClient(IOUserClient *client)
{
ELG(0, 0, 'irda', "IrDAUser: connect client");
return (kIOReturnSuccess);
}
IOReturn
IrDAUserClient::registerNotificationPort(mach_port_t port, UInt32 type)
{
ELG(0, 0, 'irda', "IrDAUser: register notification ignored");
return (kIOReturnUnsupported);
}
IOExternalMethod *
IrDAUserClient::getExternalMethodForIndex(UInt32 index)
{
IOExternalMethod *result = NULL;
ELG(0, index, 'irda', "IrDAUser: get external method");
if (index == 0) {
result = &fMethods[0];
}
return (result);
}
IOReturn
IrDAUserClient::userPostCommand(void *pIn, void *pOut, IOByteCount inputSize, IOByteCount *outPutSize)
{
if (pIn && pOut && inputSize > 0) {
unsigned char *input = (unsigned char *)pIn;
switch(*input) {
case kIrDAUserCmd_GetLog:
return getIrDALog(pIn, pOut, inputSize, outPutSize);
case kIrDAUserCmd_GetStatus:
return getIrDAStatus(pIn, pOut, inputSize, outPutSize);
case kIrDAUserCmd_Enable:
return setIrDAState(true);
case kIrDAUserCmd_Disable:
return setIrDAState(false);
default:
IOLog("IrDA: Bad command to userPostCommand, %d\n", *input);
}
}
else IOLog("IrDA: pin/pout,size error\n");
return kIOReturnBadArgument;
}
IOReturn
IrDAUserClient::getIrDALog(void *pIn, void *pOut, IOByteCount inputSize, IOByteCount *outPutSize)
{
#if (hasTracing > 0)
IOMemoryDescriptor *md; unsigned char *input = (unsigned char *)pIn;
vm_address_t bigaddr;
IOByteCount biglen;
IrDALogInfo *info;
require(inputSize == 9, Fail);
require(outPutSize, Fail);
require(*outPutSize == sizeof(IrDALogInfo), Fail);
bigaddr = input[1] << 24 | input[2] << 16 | input[3] << 8 | input[4];
biglen = input[5] << 24 | input[6] << 16 | input[7] << 8 | input[8];
md = IOMemoryDescriptor::withAddress(bigaddr, biglen, kIODirectionOutIn, fTask); require(md, Fail);
info = IrDALogGetInfo();
bcopy(info, pOut, sizeof(*info)); *outPutSize = sizeof(*info);
if (biglen >= info->hdrSize + info->eventLogSize + info->msgBufferSize) {
IOByteCount ct;
IOReturn rc;
rc = md->prepare(kIODirectionNone);
if (rc) {ELG(-1, rc, 'irda', "prepare failed"); }
ct = md->writeBytes(0, info->hdr, info->hdrSize);
if (ct != info->hdrSize) ELG(-1, rc, 'irda', "write of hdr failed");
ct = md->writeBytes(info->hdrSize, info->eventLog, info->eventLogSize);
if (ct != info->eventLogSize) ELG(-1, rc, 'irda', "write of events failed");
ct = md->writeBytes(info->hdrSize+info->eventLogSize, info->msgBuffer, info->msgBufferSize);
if (ct != info->msgBufferSize) ELG(-1, rc, 'irda', "write of msgs failed");
ELG(0, info->hdrSize+info->eventLogSize, 'irda', "wrote msgs at offset");
rc = md->complete(kIODirectionNone);
if (!rc) { ELG(0, 0, 'irda', "complete worked"); }
else { ELG(-1, rc, 'irda', "complete failed"); }
IrDALogReset(); }
md->release();
return kIOReturnSuccess;
Fail:
#endif // hasTracing > 0
return kIOReturnBadArgument;
}
IOReturn
IrDAUserClient::getIrDAStatus(void *pIn, void *pOut, IOByteCount inputSize, IOByteCount *outPutSize)
{
IrDAComm *irda;
require(*outPutSize == sizeof(IrDAStatus), Fail);
require(fDriver, Fail);
bzero(pOut, sizeof(IrDAStatus));
irda = fDriver->GetIrDAComm();
if (irda) irda->GetIrDAStatus((IrDAStatus *)pOut);
fDriver->GetIrDAStatus((IrDAStatus *)pOut);
return kIOReturnSuccess;
Fail:
IOLog("IrDA: Failing to get status\n");
return kIOReturnBadArgument;
}
IOReturn
IrDAUserClient::setIrDAState(bool state)
{
IOReturn rtn = kIOReturnSuccess;
require(fDriver, Fail);
rtn = fDriver->SetIrDAUserClientState(state);
return rtn;
Fail:
IOLog("IrDA: Failing to set IrDA state\n");
return kIOReturnBadArgument;
}