1/*
2    File:       IrGlue.cpp
3
4    Contains:   Implementation of clients to IrDA glue
5
6
7*/
8
9#include "IrGlue.h"
10#include "IrLAP.h"
11#include "IrLMP.h"
12#include "IrLAPConn.h"
13#include "IrEvent.h"
14#include "CTimer.h"
15#include "IrDiscovery.h"
16#include "CIrDevice.h"
17#include "IrQOS.h"
18#include "IrDALog.h"
19#include "IrStream.h"
20#include "IrIASService.h"
21#include "IrIASServer.h"
22#include "IrLSAPConn.h"
23#include "IrDAUserClient.h"
24
25#include "AppleIrDA.h"
26
27#define private static
28
29#if (hasTracing > 0 && hasIrGlueTracing > 0)
30
31enum IrGlueTraceCodes
32{
33    kLogNew = 1,
34    kLogInit,
35    kLogFree,
36
37    kLogReadComplete,
38    kLogTransmitComplete,
39    kLogSetSpeedComplete,
40    kLogRunQueue,
41
42    kObtainLSAPIdEvent,
43    kReleaseLSAPIdEvent,
44
45    kConnectStartEvent,
46    kListenStartEvent,
47
48    kAllocateEventBlock,
49    kGrabEventBlock,
50    kReleaseEventBlock,
51    kDeleteEventBlock,
52
53    kStartTerminateEntry,
54    kStartTerminateExit,
55
56    kLogStartTimer,
57    kLogStopTimer,
58    kLogTimerNotifier,
59    kLogTimerNotifier1,
60    kLogTimerNotifier2,
61    kLogTimerNotifierDone,
62    kLogTimerComplete
63};
64
65private
66EventTraceCauseDesc IrGlueTraceEvents[] = {
67    {kLogNew,                       "irglue: Create, obj="},
68    {kLogInit,                      "irglue: Init"},
69    {kLogFree,                      "irglue: Free"},
70
71    {kLogReadComplete,              "irglue: read complete"},
72    {kLogTransmitComplete,          "irglue: transmit complete"},
73    {kLogSetSpeedComplete,          "irglue: set speed complete"},
74    {kLogRunQueue,                  "irglue: run event queue"},
75
76    {kObtainLSAPIdEvent,            "irglue: Obtain LSAP Id"},
77    {kReleaseLSAPIdEvent,           "irglue: Release LSAP Id"},
78
79    {kConnectStartEvent,            "irglue: Connect request, myid, peerid, deviceaddr"},
80    {kListenStartEvent,             "irglue: Listen request"},
81
82    {kAllocateEventBlock,           "irglue: Allocate Event Block"},
83    {kGrabEventBlock,               "irglue: Grab Event Block"},
84    {kReleaseEventBlock,            "irglue: Release Event Block"},
85    {kDeleteEventBlock,             "irglue: Delete Event Block"},
86
87    {kStartTerminateEntry,          "irglue: Disconnected - start"},
88    {kStartTerminateExit,           "irglue: Disconnected - done"},
89
90    {kLogStartTimer,                "irglue: Start timer delay, #"},
91    {kLogStopTimer,                 "irglue: Stop timer #"},
92    {kLogTimerNotifier,             "irglue: timer notifier, id="},
93    {kLogTimerNotifier1,                "irglue: timer notifier, owner="},
94    {kLogTimerNotifier2,                "irglue: timer notifier, timesrc="},
95    {kLogTimerNotifierDone,         "irglue: timer notifier finished"},
96    {kLogTimerComplete,             "irglue: timer complete, signature="}
97
98};
99
100#define XTRACE(x, y, z) IrDALogAdd (x, y, (uintptr_t)z & 0xffff, IrGlueTraceEvents, true )
101#else
102    #define XTRACE(x, y, z) ((void)0)
103#endif
104
105static void TimerNotifier(OSObject *owner, IrDATimerEventSource *sender);
106
107//
108// Todo: move this to a more public spot if they are needed elsewhere
109//
110const UInt8 kIASDeviceClassStr[]        = "Device";
111const UInt8 kIASDeviceNameAttrStr[]     = "DeviceName";
112const UInt8 kIASDeviceName[]            = "Macintosh";
113const UInt8 kIASLMPSupportAttrStr[]     = "IrLMPSupport";
114const UInt8 kIASLMPSupportValue[]       = { 0x01, 0x00, 0x00};  // Version 1, no additional IAS support, no additional LMP support
115
116//--------------------------------------------------------------------------------
117
118#define super OSObject
119    OSDefineMetaClassAndStructors(TIrGlue, OSObject);
120
121
122//--------------------------------------------------------------------------------
123//      TIrGlue
124//--------------------------------------------------------------------------------
125/*static*/
126TIrGlue *
127TIrGlue::tIrGlue(AppleIrDASerial *driver, AppleIrDA *appleirda, IOWorkLoop *workloop, USBIrDAQoS *qos)
128{
129    TIrGlue *obj = new TIrGlue;
130
131    XTRACE(kLogNew, 0, obj);
132
133    if (obj && !obj->init(driver, appleirda, workloop, qos)) {
134	obj->release();
135	obj = nil;
136    }
137    return obj;
138}
139
140Boolean TIrGlue::init(AppleIrDASerial *driver, AppleIrDA *appleirda, IOWorkLoop *workloop, USBIrDAQoS *qos)
141{
142    IrDAErr err;
143    int i;
144
145    XTRACE(kLogInit, 0, 0);
146
147    fAppleIrDA = appleirda;
148
149    bzero(fTimers, sizeof(fTimers));
150
151    fLSAPIdsInUse = (UInt32) (1 << kNameServerLSAPId);      // name server (why doesn't it reserve it?)
152
153    fIrLAP = nil;
154    fIrLMP = nil;
155    fIrLAPConn = nil;
156    fIrDevice = nil;
157    fIrDiscovery = nil;
158    fMyQOS = fPeerQOS = nil;
159    fNameServer = nil;
160    fNameService = nil;
161
162    fLastState = kIrDAStatusOff;
163
164    if (!super::init()) return false;
165
166
167    // Set up the the event block list
168    err = TIrEvent::InitEventLists();
169    nrequire(err, Fail);
170
171    // Set up the three timers
172    for (i = 0; i < kNumTimers; i++) {
173	fTimers[i] = CTimer::cTimer(workloop, this, &::TimerNotifier);
174	require (fTimers[i], Fail);
175    }
176
177    // and the two qos objects, lap needs these at init time
178    fMyQOS =  TIrQOS::tIrQOS(qos);
179    fPeerQOS = TIrQOS::tIrQOS(qos);
180
181    // create LAP - todo: can now take the qos pointers out of the event requests
182    fIrLAP = TIrLAP::tIrLAP(this, fMyQOS, fPeerQOS);
183    require(fIrLAP, Fail);
184
185    // create LMP
186    fIrLMP = TIrLMP::tIrLMP(this);
187    require(fIrLMP, Fail);
188
189    // create LAPConn
190    fIrLAPConn = TIrLAPConn::tIrLAPConn(this);
191    require(fIrLAPConn, Fail);
192
193    // create IrDevice
194    fIrDevice = CIrDevice::cIrDevice(this, driver);
195    require(fIrDevice, Fail);
196
197    fNameService = TIASService::tIASService();      // make our IAS database
198    require(fNameService, Fail);
199
200    fNameServer = TIASServer::tIASServer(this, fNameService);
201    require(fNameServer, Fail);
202
203    // Create the discovery object
204    fIrDiscovery = CIrDiscovery::cIrDiscovery(this);
205    require(fIrDiscovery, Fail );
206
207    // Finally, load the IAS database with a few defaults
208    require(InitNameService(), Fail);
209
210    fNameServer->ListenStart();         // start the ias server
211
212    return true;
213
214Fail:
215    // we could free stuff here, but our real free routine will be
216    // called when we're released, wait until then.
217
218    XTRACE(kLogInit, 0xdead, 0xbeef);
219    return false;
220
221} // TIrGlue::Init
222
223
224//--------------------------------------------------------------------------------
225//      free
226//--------------------------------------------------------------------------------
227#define FREE(x) {if (x) { (x)->release(); x = nil; } }
228void
229TIrGlue::free()
230{
231    int i;
232
233    XTRACE(kLogFree, 0, this);
234
235
236    for (i = 0 ; i < kNumTimers; i++) {     // first, stop and free the timers
237	FREE(fTimers[i]);
238    }
239
240    FREE(fMyQOS);
241    FREE(fPeerQOS);
242    FREE(fIrDiscovery);
243    FREE(fIrDevice);
244    FREE(fIrLAPConn);
245    FREE(fIrLMP);
246    FREE(fIrLAP);
247    FREE(fNameServer);
248    FREE(fNameService);
249
250    TIrEvent::DeleteEventLists();       // release all the pending events (do last)
251
252    super::free();
253
254} // TIrGlue::free
255
256void
257TIrGlue::ReadComplete(UInt8 *buffer, UInt32 length)
258{
259    XTRACE(kLogReadComplete, length >> 16, length);
260
261    if (fIrDevice)
262	fIrDevice->ReadComplete(buffer, length);
263}
264
265void
266TIrGlue::TransmitComplete(Boolean worked)
267{
268    XTRACE(kLogTransmitComplete, 0, worked);
269
270    if (fIrDevice)
271	fIrDevice->TransmitComplete(worked);
272}
273
274void
275TIrGlue::SetSpeedComplete(Boolean worked)
276{
277    XTRACE(kLogSetSpeedComplete, 0, worked);
278
279    if (fIrDevice)
280	fIrDevice->SetSpeedComplete(worked);
281}
282
283void
284TIrGlue::RunQueue(void)
285{
286    IrDAStatus status;
287
288    XTRACE(kLogRunQueue, 0, 0);
289
290    TIrStream::RunQueue();
291
292    XTRACE(kLogRunQueue, 0x1111, 0x1111);
293
294    GetIrDAStatus(&status);
295    XTRACE(kLogRunQueue, 0x2222, 0x2222);
296
297    if (fLastState != status.connectionState) {
298	fLastState = status.connectionState;
299	    XTRACE(kLogRunQueue, 0x3333, 0x3333);
300	if (fAppleIrDA)
301	    fAppleIrDA->messageClients(kIrDACallBack_Status, &fLastState, 1);
302    }
303    XTRACE(kLogRunQueue, 0xffff, 0xffff);
304}
305
306void
307TIrGlue::Start()
308{
309    if (fIrDevice)
310	fIrDevice->Start();
311
312    fLastState = kIrDAStatusIdle;
313    if (fAppleIrDA)
314	fAppleIrDA->messageClients(kIrDACallBack_Status, &fLastState, 1);
315}
316
317void
318TIrGlue::Stop()
319{
320    int i;
321
322    if (fIrDevice)          // first stop trying to talk back to the device
323	fIrDevice->Stop();
324
325    // stop all the timers
326    for (i = 0 ; i < kNumTimers; i++)
327	StopTimer(i);
328
329    Disconnected(true);     // reset lap and lmp and the qos objects
330
331    fLastState = kIrDAStatusOff;
332    if (fAppleIrDA)
333	fAppleIrDA->messageClients(kIrDACallBack_Status, &fLastState, 1);
334}
335
336#pragma mark ---- Event blocks
337
338// just layered over IrEvent static functions, used to be imp'd here
339
340TIrEvent *
341TIrGlue::GrabEventBlock(UInt32 event, UInt32 size)
342{
343    return TIrEvent::GrabEventBlock(event, size);
344}
345
346void
347TIrGlue::ReleaseEventBlock(TIrEvent* reqBlock)
348{
349    return TIrEvent::ReleaseEventBlock(reqBlock);
350}
351
352#pragma mark ---- Timers
353
354//--------------------------------------------------------------------------------
355//      StartTimer
356//--------------------------------------------------------------------------------
357void TIrGlue::StartTimer(int id, TTimeout timeDelay, UInt32 refCon)
358{
359    XTRACE(kLogStartTimer, id, timeDelay);
360    require(id < kNumTimers && id >= 0, Fail);
361
362    if (fTimers[id])
363	fTimers[id]->StartTimer(timeDelay, refCon);
364
365Fail:
366    return;
367
368} // TIrGlue::StartTimer
369
370
371//--------------------------------------------------------------------------------
372//      StopTimer
373//--------------------------------------------------------------------------------
374void TIrGlue::StopTimer(int id)
375{
376    XTRACE(kLogStopTimer, 0, id);
377    require(id < kNumTimers && id >= 0, Fail);
378
379    if (fTimers[id])
380	fTimers[id]->StopTimer();
381
382Fail:
383    return;
384
385} // TIrGlue::StopTimer
386
387
388//--------------------------------------------------------------------------------
389//      TimerComplete
390//--------------------------------------------------------------------------------
391void TIrGlue::TimerComplete(UInt32 refCon)
392{
393    XTRACE(kLogTimerComplete, 0, refCon);
394
395    if ((refCon >= kIrFirstIrLAPTimerEvent) && (refCon <= kIrLastIrLAPTimerEvent)) {
396	fIrLAP->TimerComplete(refCon);      // send lap its timers
397    }
398    else
399    if ((refCon >= kIrFirstIrLMPTimerEvent) && (refCon <= kIrLastIrLMPTimerEvent)) {
400	fIrLMP->TimerComplete(refCon);
401    }
402
403    // Let's run the queue until it's empty now that a timer has fired and
404    // we've probably queued up some work to do.
405    RunQueue();
406} // TIrGlue::TimerComplete
407
408
409//--------------------------------------------------------------------------------
410//      TimerNotifier: Completion proc for all timers
411//--------------------------------------------------------------------------------
412private
413void TimerNotifier(OSObject *owner, IrDATimerEventSource *iotimer)
414{
415    TIrGlue *obj;
416
417    XTRACE(kLogTimerNotifier1, 0, owner);
418    XTRACE(kLogTimerNotifier2, 0, iotimer);
419
420    require(owner, Failed);
421    require(iotimer, Failed);
422
423    obj = OSDynamicCast(TIrGlue, owner);
424    require(obj, Failed);
425
426    for (int i = 0 ; i < kNumTimers; i++) {
427	CTimer *ctimer = obj->GetTimer(i);
428	if (ctimer && ctimer->GetIOTimer() == iotimer) {    // found our CTimer, finally (joke: only 3 of them)
429	    XTRACE(kLogTimerNotifier, 0, i);
430	    obj->TimerComplete(ctimer->GetSignature());     // call timeout routine
431	    XTRACE(kLogTimerNotifierDone, 0xffff, 0xffff);
432	    return;
433	}
434    }
435
436Failed:
437    XTRACE(kLogTimerNotifier, 0xdead, 0xbeef);
438    return;
439}
440
441#pragma mark ---- Lap Async Disconnect
442
443//--------------------------------------------------------------------------------
444//      Disconnected
445//--------------------------------------------------------------------------------
446void TIrGlue::Disconnected(Boolean reset_lap)
447{
448    //int review_async_disconnect;        // check both kinds of disconnect and verify they work
449
450    XTRACE(kStartTerminateEntry, 0, reset_lap);
451
452    fMyQOS->Reset();
453    fPeerQOS->Reset();
454
455    if (reset_lap) {
456	fIrLMP->Reset();            // clean up pending i/o
457	fIrLAP->Reset();            // then release the buffers
458    }
459    XTRACE(kStartTerminateExit, 0, 0);
460} // TIrGlue::Disconnected
461
462//--------------------------------------------------------------------------------
463//      IsLAPConnected (move?)
464//--------------------------------------------------------------------------------
465Boolean TIrGlue::IsLAPConnected(void)           // check with lap re our connection status
466{
467    require(fIrLAP, Fail);
468    return fIrLAP->IsConnected();
469Fail:
470    return false;
471} // TIrGlue::IsLAPConnected
472
473//
474// tell lapconn to disconnect now, don't wait for idle timer to fire
475//
476void TIrGlue::DoIdleDisconnect()
477{
478    require(fIrLAPConn, Fail);
479    fIrLAPConn->DoIdleDisconnect();
480Fail:
481    return;
482}
483
484#pragma mark ---- Name and LSAPId Service
485
486
487//--------------------------------------------------------------------------------
488//      InitNameService
489//--------------------------------------------------------------------------------
490Boolean TIrGlue::InitNameService()
491{
492    IrDAErr err;
493
494    // Add an entry for class "Device", attribute "DeviceName"
495    // Set to string "Macintosh"
496    err = fNameService->AddStringEntry(kIASDeviceClassStr, kIASDeviceNameAttrStr, kIASDeviceName, kIASCharSetAscii, 0);
497    nrequire(err, Fail);
498
499    // Add an entry for class "Device", attribute "IrLMPSupport"
500    // Set to 0x01, 0x00, 0x00 (version 1, no extra ias support, no extra LMP support)
501    err = fNameService->AddNBytesEntry(kIASDeviceClassStr, kIASLMPSupportAttrStr, kIASLMPSupportValue, sizeof(kIASLMPSupportValue));
502    nrequire(err, Fail);
503
504    return true;
505
506Fail:
507    return false;
508
509} // TIrGlue::InitNameService
510
511//--------------------------------------------------------------------------------
512//      ObtainLSAPId
513//--------------------------------------------------------------------------------
514IrDAErr TIrGlue::ObtainLSAPId( UInt32 & desiredLSAPId )
515{
516    UByte lsapId;
517
518    if (fLSAPIdsInUse == 0xFFFFFFFF) {
519	DebugLog("TIrGlue::ObtainLSAPId: no more LSAP Ids available");
520	return kIrDAErrResourceNotAvailable;
521    }
522
523    if (desiredLSAPId == kAssignDynamicLSAPId) {
524	lsapId = (UByte)random() & 0x1F;    // Random starting point between 0 and 31
525    }
526    else {
527	if (desiredLSAPId > 0x1F /*kLastValidLSAPId*/) {
528	    DebugLog("TIrGlue::ObtainLSAPId: LSAP id out of range");
529	    return kIrDAErrBadParameter;
530	}
531	lsapId = (UByte)desiredLSAPId;  // Try to get the one requested
532    }
533
534    while ((lsapId == 0) || (fLSAPIdsInUse & (1 << lsapId))) {
535	lsapId = (lsapId + 1) & 0x1F;
536    }
537
538    if ((desiredLSAPId != kAssignDynamicLSAPId) && (lsapId != desiredLSAPId)) {
539	// Wanted a specific lsapId, but its already being taken
540	return kIrDAErrResourceNotAvailable;
541    }
542
543    desiredLSAPId = (ULong)lsapId;
544    fLSAPIdsInUse |= (1 << lsapId);
545    XTRACE(kObtainLSAPIdEvent, lsapId, fLSAPIdsInUse);
546
547    return noErr;
548
549} // TIrGlue::ObtainLSAPId
550
551
552//--------------------------------------------------------------------------------
553//      ReleaseLSAPId
554//--------------------------------------------------------------------------------
555void TIrGlue::ReleaseLSAPId( UInt32 lsapId)
556{
557    check( lsapId != kNameServerLSAPId );
558    check( lsapId < 32 );
559    check( fLSAPIdsInUse & (1 << lsapId) );
560
561    fLSAPIdsInUse &= ~(1 << lsapId);
562    XTRACE( kReleaseLSAPIdEvent, lsapId, fLSAPIdsInUse );
563
564} // TIrGlue::ReleaseLSAPId
565
566//--------------------------------------------------------------------------------
567//      RegisterMyNameAndLSAPId
568//--------------------------------------------------------------------------------
569IrDAErr TIrGlue::RegisterMyNameAndLSAPId(UInt8 * className, UInt8 * attrName, UInt32 * reqLSAP)
570{
571    IrDAErr     result = kIrDAErrWrongState;
572    UInt32      tempLSAP = *reqLSAP;                    // Load the clients requested LSAP
573
574    require(fNameService, Fail);
575    require(className, Fail);
576    require(attrName, Fail);
577
578    // Obtain the lsapId
579    result = ObtainLSAPId(tempLSAP);
580    nrequire(result, Fail);
581
582    *reqLSAP = tempLSAP;
583
584    // Register my lsap-id with the name service
585    result = fNameService->AddIntegerEntry(className, attrName, tempLSAP );
586    nrequire(result, Fail_RegisterLSAPId);
587
588    return noErr;
589
590Fail_RegisterLSAPId:
591
592    ReleaseLSAPId( ( UByte )tempLSAP );
593
594Fail:
595    return result;
596
597} // TIrGlue::RegisterMyNameAndLSAPId
598
599
600
601//======================== Start / Completion routines ===========================
602
603#pragma mark ---- Connect and Listen
604
605//--------------------------------------------------------------------------------
606//      ConnectStart
607//--------------------------------------------------------------------------------
608IrDAErr TIrGlue::ConnectStart(  TIrStream   *   client,     // Caller
609				UInt32          myLSAPId,   // Reseved by RegisterMyNameAndLSAPID
610				UInt32          devAddr,    // Determined through LAP Discovery
611				UInt32          peerLSAPId, // Determined through IAS Query
612				CBuffer     *   clientData,
613				TLSAPConn   **  theLSAP     )   // Returned to caller
614{
615    TIrConnLstnRequest  *connectRequest = nil;
616    TLSAPConn           *lsap = nil;
617
618    XTRACE( kConnectStartEvent, ( myLSAPId<<8 ) + peerLSAPId, devAddr );
619
620    connectRequest = (TIrConnLstnRequest*)GrabEventBlock(kIrConnectRequestEvent);
621    require(connectRequest, Fail);
622
623    if (*theLSAP == nil) {                              // if the caller doesn't already have an LSAPConn ...
624	lsap = TLSAPConn::tLSAPConn(this, client);      // build one
625	require(lsap, Fail_NewLSAPConn);
626
627	// Assign the lsap-id for the LSAPConn (client already reseved it with RegisterMyNameAndLSAPID)
628	lsap->AssignId(myLSAPId);
629
630	*theLSAP = lsap;                // Give the lsap to the client
631    }
632    else
633	lsap = *theLSAP;                // jdg: the caller is giving us the lsapconn from last time
634
635//  IOLog("glue connnect qos baud is 0x%x\n", GetMyQOS()->SetBaudRate(k57600bps));  // DEBUGGING
636
637    // Initiate the connect for my LSAPConn
638    connectRequest->fDevAddr    = devAddr;
639    connectRequest->fLSAPId     = (UInt8)peerLSAPId;
640    connectRequest->fMyQOS      = GetMyQOS();
641    connectRequest->fPeerQOS    = GetPeerQOS();
642    connectRequest->fData       = clientData;
643    connectRequest->fClient     = client;
644
645    lsap->EnqueueEvent(connectRequest);
646
647    return noErr;
648
649    // Out of memory error exit points
650Fail_NewLSAPConn:
651    ReleaseEventBlock(connectRequest);
652
653Fail:
654    return kIrDAErrNoMemory;
655} // TIrGlue::ConnectStart
656
657
658//--------------------------------------------------------------------------------
659//      ListenStart
660//--------------------------------------------------------------------------------
661IrDAErr TIrGlue::ListenStart(   TIrStream   *   client,         // Caller
662				UInt32          lsapId,         // Preallocated LSAP Id
663				CBuffer     *   clientData,     // Data to pass with connect
664				TLSAPConn   **  theLSAP     )   // The allocated LSAP
665{
666    TLSAPConn           *lsap;
667    TIrConnLstnRequest  *listenRequest;
668
669    XTRACE(kListenStartEvent, lsapId, 0);
670
671    listenRequest = (TIrConnLstnRequest *)GrabEventBlock(kIrListenRequestEvent);
672    require(listenRequest, Fail);
673
674    if (*theLSAP == nil) {                              // if the caller doesn't already have an LSAPConn ...
675	lsap = TLSAPConn::tLSAPConn(this, client);      // Create and init new LSAPConn
676	require(lsap, Fail_NewLSAPConn);
677
678							// Note: Caller has already registered with IAS
679	lsap->AssignId( lsapId );                       // Assign the lsap-id for the LSAPConn
680
681	*theLSAP = lsap;                                // return the new lsap to the client
682    }
683    else
684	lsap = *theLSAP;                                // the caller is giving us the lsapconn from last time
685
686
687    listenRequest->fMyQOS   = GetMyQOS();
688    listenRequest->fPeerQOS = GetPeerQOS();
689    listenRequest->fData    = clientData;
690
691    lsap->EnqueueEvent( listenRequest );
692
693    return noErr;
694
695Fail_NewLSAPConn:                                   // Out of memory error exit points
696
697    ReleaseEventBlock(listenRequest);
698
699Fail:
700
701    return kIrDAErrNoMemory;
702} // TIrGlue::ListenStart
703
704// statistics
705void
706TIrGlue::GetIrDAStatus(IrDAStatus *status)
707{
708    Boolean connected = false;
709    Boolean discoverActive = false;
710    Boolean brokenConnection = false;
711
712    if (fIrDevice && fIrLAP && status) {
713	fIrDevice->GetStatus(status);       // get the statistics record (ugh, we stomp on it here)
714
715	connected           = fIrLAP->IsConnected();
716	brokenConnection    = fIrLAP->InBrokenBeam();
717	discoverActive      = fIrLAP->Discovering();
718
719	if( brokenConnection )
720	    status->connectionState = kIrDAStatusBrokenConnection;
721	else
722	    if( connected )
723		status->connectionState = kIrDAStatusConnected;
724	    else
725		if( discoverActive )
726		    status->connectionState = kIrDAStatusDiscoverActive;
727		else
728		    status->connectionState = kIrDAStatusIdle;
729
730	status->connectionSpeed = fIrDevice->GetSpeed();
731	fIrLAP->GetNickName(status->nickName, sizeof(status->nickName));
732    }
733}
734
735#ifdef NOT_NOW
736#pragma mark ------------------ NOT NOW ----------
737
738
739
740
741extern "C"
742pascal void XDeferredTaskProc( void *parm );        // test test test test
743
744
745//--------------------------------------------------------------------------------
746//      Init
747//--------------------------------------------------------------------------------
748NewtonErr TIrGlue::Init()
749{
750    NewtonErr result;
751    OSErr err;
752
753    XTRACE(kInit, (int)this >> 16, this);
754
755    gIrDAPrefs.Init();          // initialize the irda prefs from iqos resources
756				// note this gets Reset each time the ir hardware is changed (ugh!)
757
758
759    fMyQOS.Reset();                             // now that we have hardware, get matching QoS values
760    fPeerQOS.Reset();
761
762    result = InitEventBlockList();
763    nrequire( result, Fail_Init );
764
765    result = fIrLAP.Init(this, &fIrLMP);        // Initialize IrLAP -- FIX LAP TO NOT KEEP A LMP PTR
766    nrequire( result, Fail_Init );
767
768    result = fIrLMP.Init(this, &fIrLAP);        // Initialize IrLMP -- FIX LMP TO NOT KEEP A LAP PTR
769    nrequire( result, Fail_Init );
770
771    result = fIrDiscovery.Init( this );
772    nrequire( result, Fail_Init );
773
774    InitNameService();
775
776    return noErr;
777
778Fail_Init:
779
780    DeInit();               // reset
781    return -1;
782
783} // TIrGlue::Init
784
785
786//--------------------------------------------------------------------------------
787//      DeInit
788//--------------------------------------------------------------------------------
789void TIrGlue::free(void)
790{
791    XTRACE(kDeInit, 0, 0);
792
793    // let's stop the timers right away ...
794    fTimer1.DeInit();
795    fTimer2.DeInit();
796    fTimer3.DeInit();
797
798
799    // Free the event block list and any event blocks on it
800    DeleteEventBlockList();
801
802} // TIrGlue::DeInit
803
804
805#endif // NOT_NOW
806