1//
2//  GetEntry.m
3//  IrDA Status
4//
5//  Created by jwilcox on Mon Apr 23 2001.
6//  Copyright (c) 2001 Apple Computer, Inc. All rights reserved.
7//
8
9#import "GetEntry.h"
10#import "LogItem.h"
11#import "preferences.h"
12
13@implementation GetEntry
14
15static	char			gBigBuffer[1024*1024];	// fix: do two passes and allocate the appropriate size
16static	IrDALogInfo		gInfo;					// pointers and sizes returned directly
17
18void OutputBuffer(IrDALogHdr *obj, IrDAEventDesc *events, char *msgs, NSMutableArray *logItems)
19{	
20	IrDAEventDescPtr	eventPtr;									
21	Boolean 			oldTracingFlag;
22	
23	if (obj->fWrapped == false &&					// if we've not wrapped around and
24		obj->fEventIndex == obj->fPrintIndex) {		// print index == new event index, then nothing new
25		return;
26	}
27	oldTracingFlag = obj->fTracingOn;			// Save old value of tracing enabled bit
28	obj->fTracingOn = false;					// temporarily turn off tracing during dcmd (let's not race)
29	if (obj->fWrapped) {						// if adding new entries wrapped over print index
30		obj->fPrintIndex = obj->fEventIndex;	// then start printing at next "avail" entry
31	}
32	if( obj->fPrintIndex >= obj->fNumEntries )	// sanity check only, this shouldn't happen
33		obj->fPrintIndex = 0;
34	do{						
35		char			*msg;
36							
37		eventPtr = &obj->fEventBuffer[obj->fPrintIndex];
38		eventPtr = (eventPtr - gInfo.eventLog) + events;		// adjust event ptr for kernel/user address space change
39		msg = (eventPtr->msg - gInfo.msgBuffer) + msgs;			// adjust msg ptr too
40		[logItems addObject: [LogItem logItemWithValues: eventPtr->timeStamp: eventPtr->data1: eventPtr->data2: [NSString stringWithCString:msg]]];
41		obj->fPrintIndex++;
42		
43		if( obj->fPrintIndex >= obj->fNumEntries )	// wrap print index at end of circular buffer
44			obj->fPrintIndex = 0;
45			
46	} while((obj->fPrintIndex != obj->fEventIndex) );
47	
48	obj->fPrintIndex = obj->fEventIndex;	// FLUSH PENDING LOG ENTRIES if aborted
49											// we shouldn't do this once we get a -C flag :-)
50	obj->fWrapped = false;					// reset wrapped flag
51	obj->fTracingOn = oldTracingFlag;		// restore tracing state (enable again)
52}
53
54// return true if there are messages to dump
55Boolean CheckLog(IrDALogHdr *obj)
56{
57	if (obj->fWrapped == false &&					// if we've not wrapped around and
58		obj->fEventIndex == obj->fPrintIndex) {		// print index == new event index, then nothing new
59		return false;
60	}
61	return true;
62}
63
64void DumpLog(NSMutableArray *logItems)
65{
66	IrDALogHdr 		*hdr	= (IrDALogHdr *)&gBigBuffer[0];
67	IrDAEventDesc	*events	= (IrDAEventDescPtr)&gBigBuffer[gInfo.hdrSize];
68	char 			*msgs	= (char *)&gBigBuffer[gInfo.hdrSize + gInfo.eventLogSize];
69	
70	if (CheckLog(hdr)) {				// if any new entries
71		OutputBuffer(hdr, events, msgs, logItems);
72	}
73}
74
75kern_return_t doCommand(io_connect_t con, unsigned char commandID, void *inputData, unsigned long inputDataSize, void *outputData, size_t *outputDataSize)
76{
77	kern_return_t   err = KERN_SUCCESS;
78	//mach_msg_type_number_t  outSize = outputDataSize;
79	IrDACommandPtr command = NULL;
80	
81	// Creates a command block:
82	command = (IrDACommandPtr)malloc (inputDataSize + sizeof (unsigned char));
83	if (!command)
84		return KERN_FAILURE;
85	command->commandID = commandID;
86	// Adds the data to the command block:
87	if ((inputData != NULL) && (inputDataSize != 0))
88		memcpy(command->data, inputData, inputDataSize);
89	// Now we can (hopefully) transfer everything:
90	err = IOConnectCallStructMethod(
91			con,
92			0,										/* method index */
93			(char *) command,						/* input[] */
94			inputDataSize+sizeof(unsigned char),	/* inputCount */
95			(char *) outputData,					/* output */
96			outputDataSize);						/* buffer size, then result */
97	free (command);
98	return err;
99}
100
101static kern_return_t closeDevice(io_connect_t con)
102{
103    return IOServiceClose(con);
104}
105
106static kern_return_t openDevice(io_object_t obj, io_connect_t * con)
107{
108    return IOServiceOpen(obj, mach_task_self(), 123, con);
109}
110
111/* ==========================================
112 * Look through the registry and search for an
113 * IONetworkInterface objects with the given
114 * name.
115 * If a match is found, the object is returned.
116 * =========================================== */
117io_object_t getInterfaceWithName(mach_port_t masterPort, const char *className)
118{
119    kern_return_t	kr;
120    io_iterator_t	ite;
121    io_object_t		obj = 0;
122
123    kr = IORegistryCreateIterator(masterPort, kIOServicePlane, true, &ite);
124    if (kr != kIOReturnSuccess) {
125        printf("IORegistryCreateIterator() error %08lx\n", (unsigned long)kr);
126        return 0;
127    }
128    while ((obj = IOIteratorNext(ite))) {
129        if (IOObjectConformsTo(obj, (char *) className)) {
130            break;
131        }
132		else {
133			io_name_t name;
134			kern_return_t rc;
135			rc = IOObjectGetClass(obj, name);
136		}
137        IOObjectRelease(obj);
138        obj = 0;
139    }
140    IOObjectRelease(ite);
141    return obj;
142}
143
144+ (NSString *) GetCurrentDriverName{
145	NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
146	return ([defaults objectForKey: DefaultDriverKey]);
147}
148
149+ (void) getEntry: (NSMutableArray *)logItems{
150    kern_return_t	kr;
151    io_object_t		netif;
152    io_connect_t	conObj;
153    mach_port_t		masterPort;
154	NSString		*driverName = [self GetCurrentDriverName];
155	const char		*driverCStringName = [driverName cString];
156
157    // Get master device port
158    //
159    kr = IOMasterPort(bootstrap_port, &masterPort);
160    if (kr != KERN_SUCCESS) {
161		printf("IOMasterPort() failed: %08lx\n", (unsigned long)kr);
162		return;
163    }
164    netif = getInterfaceWithName(masterPort, driverCStringName);
165    if (netif) {
166		kr = openDevice(netif, &conObj);
167		if (kr == kIOReturnSuccess) {
168			UInt32 inbuf[2];			// big buffer address passed to userclient
169			size_t infosize;
170		
171			inbuf[0] = (UInt32)&gBigBuffer[0];
172			inbuf[1] = sizeof(gBigBuffer);
173			infosize = sizeof(IrDALogInfo);
174
175			kr = doCommand(conObj, 0x12, &inbuf, sizeof(inbuf), &gInfo, &infosize);
176			if (kr == kIOReturnSuccess) {
177				DumpLog(logItems);
178			}
179			else{
180				printf("kr is %d\n", kr);
181			}
182			closeDevice(conObj);
183      	}
184		IOObjectRelease(netif);
185    }
186	else{
187		NSLog(@"Unable to find the Requested Driver");
188	}
189}
190
191@end
192