1/* 2 File: ttplmp.cpp 3 4 Contains: TinyTP's impl of the virtual callbacks in CIrLSAP 5 6*/ 7 8#include "ttp.h" 9#include "ttppdu.h" 10#include "CBufferSegment.h" 11#include "IrDALog.h" 12 13#if (hasTracing > 0 && hasTTPLMPTracing > 0) 14 15enum TTPLmpTraceCodes 16{ 17 kDiscoverComplete = 1, 18 kLSAPLookupComplete, 19 kConnected, 20 kPutComplete, 21 kGetComplete, 22 kDisconnected, 23 kConnectError, 24 kListenComplete, 25 kAcceptComplete, 26 27 kQOSrate, 28 kQOStimeout, 29 kQOSdatasize, 30 kQOSwindowsize, 31 kQOSbofs, 32 kQOSminturn, 33 kQOSlinkdisc 34 35 36}TTPLMPTraceCodes; 37 38static 39EventTraceCauseDesc gTraceEvents[] = { 40 {kDiscoverComplete, "ttplmp: discovery complete"}, 41 {kLSAPLookupComplete, "ttplmp: LSAP lookup complete"}, 42 {kConnected, "ttplmp: Connect complete, buf posn=, size="}, 43 {kPutComplete, "ttplmp: put complete, result="}, 44 {kGetComplete, "ttplmp: get complete, result=, size="}, 45 {kDisconnected, "ttplmp: disconnect event"}, 46 {kConnectError, "ttplmp: connect failed, result="}, 47 {kListenComplete, "ttplmp: listen complete, peer sap=, size="}, 48 {kAcceptComplete, "ttplmp: accept complete, result="}, 49 50 {kQOSrate, "ttplmp: qos bitrate"}, 51 {kQOStimeout, "ttplmp: qos timeout"}, 52 {kQOSdatasize, "ttplmp: qos datasize"}, 53 {kQOSwindowsize, "ttplmp: qos windowsize"}, 54 {kQOSbofs, "ttplmp: qos bofs"}, 55 {kQOSminturn, "ttplmp: qos min turn"}, 56 {kQOSlinkdisc, "ttplmp: qos link disc"} 57 58 59}; 60 61#define XTRACE(x, y, z) IrDALogAdd( x, y, (uintptr_t)z & 0xffff, gTraceEvents, true ) 62 63#else 64#define XTRACE(x, y, z) ((void)0) 65#endif 66 67unsigned const char *className = (unsigned char *)"IrLan"; 68 69#if (hasTracing > 0 && hasTTPLMPTracing > 1) 70void LogOneQOS(int id, TIrQOS *q); 71void LogQOSData(TIrQOS *myQOS, TIrQOS *peerQOS); 72#else 73#define LogQOSData(x, y) ((void)0); 74#endif 75 76//Boolean putPending = false; // one per entire system! 77 78////////////////////////////////////////////////////////////////////////////////// 79// the following are called by CIrLSAP via virtual function overloading ... 80////////////////////////////////////////////////////////////////////////////////// 81 82 83void 84TTinyTP::DiscoverComplete( // discovery has finished 85 UInt32 numFound, 86 IrDAErr result ) 87{ 88 XTRACE( kDiscoverComplete, numFound, 0 ); 89 discoverPending = false; // allow another discover request 90 91 // TinyTP doesn't do anything with this, just pass along to our client 92 TTPDiscoverComplete(numFound, result); 93 this->CheckTheQueues(); // see if we have more work to do 94} 95 96 97void 98TTinyTP::LSAPLookupComplete ( // an IAS query has finished 99 IrDAErr result, 100 UInt32 peerLSAPId) 101{ 102 XTRACE (kLSAPLookupComplete, result, peerLSAPId); 103 104 TTPLookupComplete(result, peerLSAPId); // virtual callback 105 this->CheckTheQueues(); // see if we have more work to do 106} 107 108 109void 110TTinyTP::ConnectComplete ( 111 IrDAErr result, 112 TIrQOS *myQOS, 113 TIrQOS *peerQOS, 114 CBufferSegment *data) // up to my client to free this data 115{ 116#pragma unused (myQOS, peerQOS) 117 118 //check(data); // might be nil if connect failed 119 120 if (result == noErr) { // if the connect worked 121 check(data); // should always have data on a TTP connect 122 LogQOSData(myQOS, peerQOS); // only if tracing > 1 123 XTRACE (kConnected, data->Position(), data->GetSize()); 124 BufHideRest(data); // set eof pointer, rewind 125 TTPHandleConnectConfirm(fPeerLSAPId, myQOS, peerQOS, data); // let TTP know we have connect 126 } 127 else { 128 XTRACE (kConnectError, result >> 16, result); 129 //Disconnect(); // tell CIrLSAP to disconnect (this is a nop and vanishes) 130 TTPHandleDisconnectIndication(0, nil); // foo, fake a disconnect 131 } 132 this->CheckTheQueues(); // see if we have more work to do 133} 134 135void 136TTinyTP::DisconnectComplete (void) 137{ 138 XTRACE (kDisconnected, 0, 0); 139 TTPHandleDisconnectIndication(0, nil); // sigh, where's my reason? 140 this->CheckTheQueues(); // see if we have more work to do 141} 142 143void 144TTinyTP::DataPutComplete ( 145 IrDAErr result, 146 CBufferSegment *data) // TTP "copy" of data ... foo 147{ 148 check(data); 149 XTRACE (kPutComplete, 0, result); 150 151 if (result) { //// Try and handle hangups 152 if (Connected) // if we think we're connected 153 DoDisconnectRequest(nil); // force a disconnect on error 154 } 155 156 BufFree(data); // put done, don't need the buffer anymore 157 this->CheckTheQueues(); // see if we have more work to do 158} 159 160void 161TTinyTP::DataGetComplete ( 162 IrDAErr result, 163 CBufferSegment *data) 164{ 165 XTRACE (kGetComplete, result, data->GetSize()); 166 167 if (result == noErr) { // if the read worked 168 check(data); // then, ah, there should be data 169 BufHideRest(data); // set buffer size and rewind 170 TTPHandleDataIndication(data); // pass up to TTP & TTP Client 171 } 172 else { 173 if (Connected) DoDisconnectRequest(nil); // treat err as disconnect request 174 BufFree(data); // get failed, don't need the buffer anymore 175 } 176 177 this->CheckTheQueues(); // see if we have more work to do 178} 179 180 181void 182TTinyTP::ListenComplete ( 183 IrDAErr result, 184 UInt32 peerAddr, 185 UInt32 peerLSAPId, 186 TIrQOS *myQOS, // my qos 187 TIrQOS *peerQOS, // peer's qos 188 CBufferSegment *data) 189{ 190 XTRACE (kListenComplete, 0, this); 191 XTRACE (kListenComplete, peerLSAPId, result); 192 check(data); // should always have data on a listen complete 193 194 fPeerAddr = peerAddr; // hang out to the address of our caller 195 fPeerSAP = peerLSAPId; 196 197 if (result == noErr) { // if the listen is ok 198 BufHideRest(data); // set eof pointer, rewind 199 } 200 TTPHandleConnectIndication(result, peerLSAPId, myQOS, peerQOS, data); // let TTP know listen finished 201 202 this->CheckTheQueues(); // see if we have more work to do 203} 204 205// 206// BOGUS: there isn't an accept complete return to our caller, so their 207// buffer has to be freed by us instead of by them. BOGUS. Pass it up. 208// 209void 210TTinyTP::AcceptComplete ( 211 IrDAErr result, 212 CBufferSegment *data) 213{ 214 XTRACE(kAcceptComplete, 0, result); 215 check(data); // should always have a buffer, it's allocd by DoConnectResponse() 216 //BufFree(data); // free the connect buffer allocated by PDU Connect 217 218 TTPHandleAcceptComplete(result, data); // pass up the result code and buffer ptr (client frees it now) 219 220 if (result == noErr) { // if we're fully open now 221 CBufferSegment *getBuf; 222 223 Connected = true; // change state before my callback does more work! 224 getBuf = BufAlloc(2048+5); // need up to max lap size 225 require(getBuf, NoMem); // not a lot I can do w/out a read buffer 226 DataGet(getBuf); // start the read 227 } 228NoMem: 229 this->CheckTheQueues(); // see if we have more work to do 230} 231 232void 233TTinyTP::CancelGetsComplete(IrDAErr result) 234{ 235#pragma unused(result) 236 // never gets here 237} 238 239void 240TTinyTP::CancelPutsComplete(IrDAErr result) 241{ 242#pragma unused(result) 243 // never gets here 244} 245 246 247#pragma mark ---- QoS debug logging 248 249#if (hasTracing > 0 && hasTTPLMPTracing > 1) 250 251void 252LogOneQOS(int id, TIrQOS *q) 253{ 254 check(q); 255 256 BitRate rate = q->GetBaudRate(); 257 XTRACE(kQOSrate, id, rate); 258 259 TTimeout timeout = q->GetMaxTurnAroundTime(); 260 XTRACE(kQOStimeout, id, timeout); 261 262 ULong datasize = q->GetDataSize(); 263 XTRACE(kQOSdatasize, id, datasize); 264 265 ULong windowsize = q->GetWindowSize(); 266 XTRACE(kQOSwindowsize, id, windowsize); 267 268 ULong bofs = q->GetExtraBOFs(); 269 XTRACE(kQOSbofs, id, bofs); 270 271 TTimeout minturn = q->GetMinTurnAroundTime(); 272 XTRACE(kQOSminturn, id, minturn); 273 274 TTimeout linkdisc = q->GetLinkDiscThresholdTime(); 275 XTRACE(kQOSlinkdisc, id, linkdisc); 276 277} 278 279void 280LogQOSData(TIrQOS *myQOS, TIrQOS *peerQOS) 281{ 282 LogOneQOS(1, myQOS); 283 LogOneQOS(2, peerQOS); 284} 285 286#endif // hasTTPLMPTracing > 1 287