1#import "IrDAStatus.h"
2#import "Preferences.h"
3
4@implementation IrDAStatusObj
5
6 - (void) DumpResults:(IrDAStatus *)stats
7{
8	io_name_t	temp;
9	BOOL		makeSound = NO;
10	
11	if (stats->connectionSpeed != oldStatus.connectionSpeed){
12		oldStatus.connectionSpeed = stats->connectionSpeed;
13		sprintf(temp, "%lu", stats->connectionSpeed); 
14		[connectionSpeed setStringValue: [NSString stringWithCString: temp]];
15	}
16
17	if (stats->connectionState != oldStatus.connectionState){
18		oldStatus.connectionState = stats->connectionState;
19		switch (stats->connectionState) {
20			case kIrDAStatusIdle:					[connectionState setStringValue: @"Idle"];			break;
21			case kIrDAStatusDiscoverActive:			[connectionState setStringValue: @"Discovering"];	break;
22			case kIrDAStatusConnected:				[connectionState setStringValue: @"Connected"];		break;
23			case kIrDAStatusBrokenConnection:		[connectionState setStringValue: @"Beam Broken"];	makeSound = YES;	break;
24			case kIrDAStatusOff:					[connectionState setStringValue: @"Off"];			break;
25			case kIrDAStatusInvalid:				[connectionState setStringValue: @"Invalid"];		break;
26		}
27	}
28
29	if (stats->crcErrors != oldStatus.crcErrors){
30		oldStatus.crcErrors = stats->crcErrors;
31		sprintf(temp, "%lu", stats->crcErrors); 
32		[crcErrors setStringValue: [NSString stringWithCString: temp]];
33	}
34	
35	if (stats->dataPacketsIn != oldStatus.dataPacketsIn){
36		oldStatus.dataPacketsIn = stats->dataPacketsIn;
37		sprintf(temp, "%lu", stats->dataPacketsIn); 
38		[dataPacketsIn setStringValue: [NSString stringWithCString: temp]];
39	}
40	
41	if (stats->dataPacketsOut != oldStatus.dataPacketsOut){
42		oldStatus.dataPacketsOut = stats->dataPacketsOut;
43		sprintf(temp, "%lu", stats->dataPacketsOut); 
44		[dataPacketsOut setStringValue: [NSString stringWithCString: temp]];
45	}
46	
47	if (stats->dropped != oldStatus.dropped){
48		oldStatus.dropped = stats->dropped;
49		sprintf(temp, "%lu", stats->dropped); 
50		[dropped setStringValue: [NSString stringWithCString: temp]];
51	}
52	
53	if (stats->iFrameRec != oldStatus.iFrameRec){
54		oldStatus.iFrameRec = stats->iFrameRec;
55		sprintf(temp, "%lu", stats->iFrameRec); 
56		[iFrameRec setStringValue: [NSString stringWithCString: temp]];
57	}
58	
59	if (stats->iFrameSent != oldStatus.iFrameSent){
60		oldStatus.iFrameSent = stats->iFrameSent;
61		sprintf(temp, "%lu", stats->iFrameSent); 
62		[iFrameSent setStringValue: [NSString stringWithCString: temp]];
63	}
64	
65	if (stats->ioErrors != oldStatus.ioErrors){
66		oldStatus.ioErrors = stats->ioErrors;
67		sprintf(temp, "%lu", stats->ioErrors); 
68		[ioErrors setStringValue: [NSString stringWithCString: temp]];
69	}
70	
71	[nickName setStringValue: [NSString stringWithCString: stats->nickName]];
72	
73	if (stats->protcolErrs != oldStatus.protcolErrs){
74		makeSound = YES;
75		oldStatus.protcolErrs = stats->protcolErrs;
76		sprintf(temp, "%lu", stats->protcolErrs); 
77		[protocolErrs setStringValue: [NSString stringWithCString: temp]];
78	}
79	
80	if (stats->recTimeout != oldStatus.recTimeout){
81		oldStatus.recTimeout = stats->recTimeout;
82		sprintf(temp, "%lu", stats->recTimeout); 
83		[recTimeout setStringValue: [NSString stringWithCString: temp]];
84	}
85	
86	if (stats->rejRec != oldStatus.rejRec){
87		oldStatus.rejRec = stats->rejRec;
88		sprintf(temp, "%u", stats->rejRec); 
89		[rejRec setStringValue: [NSString stringWithCString: temp]];
90	}
91	
92	if (stats->rejSent != oldStatus.rejSent){
93		oldStatus.rejSent = stats->rejSent;
94		sprintf(temp, "%u", stats->rejSent); 
95		[rejSent setStringValue: [NSString stringWithCString: temp]];
96	}
97	
98	if (stats->resent != oldStatus.resent){
99		oldStatus.resent = stats->resent;
100		sprintf(temp, "%lu", stats->resent); 
101		[resent setStringValue: [NSString stringWithCString: temp]];
102	}
103	
104	if (stats->rnrRec != oldStatus.rnrRec){
105		oldStatus.rnrRec = stats->rnrRec;
106		sprintf(temp, "%u", stats->rnrRec); 
107		[rnrRec setStringValue: [NSString stringWithCString: temp]];
108	}
109	
110	if (stats->rnrSent != oldStatus.rnrSent){
111		oldStatus.rnrSent = stats->rnrSent;
112		sprintf(temp, "%u", stats->rnrSent); 
113		[rnrSent setStringValue: [NSString stringWithCString: temp]];
114	}
115	
116	if (stats->rrRec != oldStatus.rrRec){
117		oldStatus.rrRec = stats->rrRec;
118		sprintf(temp, "%lu", stats->rrRec); 
119		[rrRec setStringValue: [NSString stringWithCString: temp]];
120	}
121	
122	if (stats->rrSent != oldStatus.rrSent){
123		oldStatus.rrSent = stats->rrSent;
124		sprintf(temp, "%lu", stats->rrSent); 
125		[rrSent setStringValue: [NSString stringWithCString: temp]];
126	}
127	
128	if (stats->srejRec != oldStatus.srejRec){
129		oldStatus.srejRec = stats->srejRec;
130		sprintf(temp, "%u", stats->srejRec); 
131		[srejRec setStringValue: [NSString stringWithCString: temp]];
132	}
133	
134	if (stats->srejSent != oldStatus.srejSent){
135		oldStatus.srejSent = stats->srejSent;
136		sprintf(temp, "%u", stats->srejSent); 
137		[srejSent setStringValue: [NSString stringWithCString: temp]];
138	}
139	
140	if (stats->uFrameSent != oldStatus.uFrameSent){
141		oldStatus.uFrameSent = stats->uFrameSent;
142		sprintf(temp, "%lu", stats->uFrameSent); 
143		[uFrameSent setStringValue: [NSString stringWithCString: temp]];
144	}
145	
146	if (stats->uFrameRec != oldStatus.uFrameRec){
147		oldStatus.uFrameRec = stats->uFrameRec;
148		sprintf(temp, "%lu", stats->uFrameRec); 
149		[uFrameRec setStringValue: [NSString stringWithCString: temp]];
150	}
151	
152	if (stats->xmitTimeout != oldStatus.xmitTimeout){
153		oldStatus.xmitTimeout = stats->xmitTimeout;
154		sprintf(temp, "%lu", stats->xmitTimeout); 
155		[xmitTimeout setStringValue: [NSString stringWithCString: temp]];
156	}
157	
158	if (makeSound){		/* local Variable */
159		NSBeep();
160	}
161}
162
163kern_return_t closeDevice(io_connect_t con)
164{
165    return IOServiceClose(con);
166}
167
168kern_return_t doCommand(io_connect_t con, unsigned char commandID, void *inputData, unsigned long inputDataSize, void *outputData, size_t *outputDataSize)
169{
170	kern_return_t   err = KERN_SUCCESS;
171	//mach_msg_type_number_t  outSize = outputDataSize;
172	IrDACommandPtr command = NULL;
173	
174	// Creates a command block:
175	command = (IrDACommandPtr)malloc (inputDataSize + sizeof (unsigned char));
176	if (!command)
177		return KERN_FAILURE;
178	command->commandID = commandID;
179	// Adds the data to the command block:
180	if ((inputData != NULL) && (inputDataSize != 0))
181		memcpy(command->data, inputData, inputDataSize);
182	// Now we can (hopefully) transfer everything:
183	err = IOConnectCallStructMethod(
184			con,
185			0,										/* method index */
186			(char *) command,						/* input[] */
187			inputDataSize+sizeof(unsigned char),	/* inputCount */
188			(char *) outputData,					/* output */
189			outputDataSize);						/* buffer size, then result */
190	free (command);
191	return err;
192}
193
194kern_return_t openDevice(io_object_t obj, io_connect_t * con)
195{
196    return IOServiceOpen(obj, mach_task_self(), 123, con);
197}
198
199/* ==========================================
200 * Look through the registry and search for an
201 * IONetworkInterface objects with the given
202 * name.
203 * If a match is found, the object is returned.
204 * =========================================== */
205io_object_t getInterfaceWithName(mach_port_t masterPort, const char *className)
206{
207    kern_return_t	kr;
208    io_iterator_t	ite;
209    io_object_t		obj = 0;
210
211    kr = IORegistryCreateIterator(masterPort, kIOServicePlane, true, &ite);
212    if (kr != kIOReturnSuccess) {
213        printf("IORegistryCreateIterator() error %08lx\n", (unsigned long)kr);
214        return 0;
215    }
216    while ((obj = IOIteratorNext(ite))) {
217        if (IOObjectConformsTo(obj, (char *) className)) {
218            break;
219        }
220		else {
221			io_name_t name;
222			kern_return_t rc;
223			rc = IOObjectGetClass(obj, name);
224		}
225        IOObjectRelease(obj);
226        obj = 0;
227    }
228    IOObjectRelease(ite);
229    return obj;
230}
231
232- (NSString *) GetCurrentDriverName{
233	NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
234	return ([defaults objectForKey: DefaultDriverKey]);
235}
236
237- (void) doTimer: (NSTimer *) myTimer{
238    kern_return_t	kr;
239    IrDAStatus		stats;
240
241	size_t outputsize = sizeof(stats);
242
243	kr = doCommand(conObj, kIrDAUserCmd_GetStatus, nil, 0, &stats, &outputsize);
244	if (kr == kIOReturnSuccess) {
245		[self DumpResults: &stats];
246	}
247	else{
248		NSLog(@"IrDAStatus.m:doTimer: doCommand failed");
249	}
250}
251- (void) InvalidateOldStatus
252 {
253	oldStatus.connectionState = -1;
254	oldStatus.connectionSpeed = -1;
255	oldStatus.dataPacketsIn = -1;
256	oldStatus.dataPacketsOut = -1;
257	oldStatus.crcErrors = -1;
258	oldStatus.ioErrors = -1;
259	oldStatus.recTimeout = -1;
260	oldStatus.xmitTimeout = -1;
261	oldStatus.iFrameRec = -1;
262	oldStatus.iFrameSent = -1;
263	oldStatus.uFrameRec = -1;
264	oldStatus.uFrameSent = -1;
265	oldStatus.dropped = -1;
266	oldStatus.resent = -1;
267	oldStatus.rrRec = -1;
268	oldStatus.rrSent = -1;
269	oldStatus.rnrRec = -1;
270	oldStatus.rnrSent = -1;
271	oldStatus.rejRec = -1;
272	oldStatus.rejSent = -1;
273	oldStatus.srejRec = -1;
274	oldStatus.srejSent = -1;
275	oldStatus.protcolErrs = -1;
276 }
277- (IBAction)StartTimer:(id)sender
278{
279	if (state){
280		NSLog(@"Stop timer now!");
281		[timer invalidate];
282		// Display and keep track of state in button
283		closeDevice(conObj);
284		[sender setTitle: @"Start"];
285		state = false;
286	}
287	else{
288		mach_port_t		masterPort;
289		io_object_t		netif;
290		kern_return_t	kr;
291		NSString		*driverName = [self GetCurrentDriverName];
292		const char		*driverCStringName = [driverName cString];
293		
294		// Get master device port
295		//
296		kr = IOMasterPort(bootstrap_port, &masterPort);
297		if (kr != KERN_SUCCESS) {
298			return;
299		}
300		netif = getInterfaceWithName(masterPort, driverCStringName);
301		if (netif) {
302			kr = openDevice(netif, &conObj);
303			if (kr == kIOReturnSuccess) {
304				NSLog(@"Start timer now!");
305				[self InvalidateOldStatus];
306				timer = [NSTimer scheduledTimerWithTimeInterval: .1 target: self selector: @selector(doTimer:) userInfo: nil repeats: YES];
307		
308				// Display and keep track of state in button
309				[sender setTitle: @"Stop"];
310				
311				state = true;
312			}
313			else{
314				NSLog(@"IrDAStatus.m:StartTimer: openDevice failed");
315			}
316		IOObjectRelease(netif);
317		}
318		else{
319			NSLog(@"IrDAStatus.m:StartTimer: getInterfaceWithName failed");
320		}
321	}
322}
323
324@end
325