1/* 2 File: ttp2.cpp 3 4 Contains: Tiny TP Implementations of callbacks by CIrLSAP 5 6 7*/ 8 9#include "ttp.h" 10#include "ttppdu.h" 11#include "CBufferSegment.h" 12 13// Contents: this module contains all of the TinyTP callbacks that 14// are invoked (one way or another) by CIrLSAP when something 15// happens worth telling us about 16 17#if (hasTracing > 0 && hasTTP2Tracing > 0) 18 19enum IrTinyTP2TraceCodes 20{ 21 kHandleConnectIndication = 1, 22 kHandleConnectConfirm, 23 kHandleDisconnectIndication, 24 kHandleDataIndication, 25 kDataLessPacket 26}; 27 28static 29EventTraceCauseDesc gTraceEvents[] = { 30 {kHandleConnectIndication, "TinyTP2: connect indication"}, 31 {kHandleConnectConfirm, "TinyTP2: connect confirm"}, 32 {kHandleDisconnectIndication, "TinyTP2: disconnect indication"}, 33 {kHandleDataIndication, "TinyTP2: data indication"}, 34 {kDataLessPacket, "TinyTP2: dataless indication"} 35}; 36 37#define XTRACE(x, y, z) IrDALogAdd( x, y, z, gTraceEvents, true ) 38 39#else 40 #define XTRACE(x, y, z) ((void)0) 41#endif 42 43 44void 45TTinyTP::TTPHandleConnectIndication ( 46 IrDAErr result, 47 TTPSAP sap, // calling TTP SAP 48 TIrQOS *ourQOS, // our QoS 49 TIrQOS *peerQOS, // peer QoS 50 TTPBuf *userData) // calling UserData 51{ 52 unsigned char plist[100]; // enough for me ... 53 int p; // parameters? 54 int n; // initial credit 55 56 XTRACE(kHandleConnectIndication, 0, result); 57 if (result != noErr) { 58 TTPConnectIndication(result, sap, ourQOS, peerQOS, this->TxMaxSduSize, userData); // virtual callback 59 return; 60 } 61 62 ttp_pdu_connect_parse(userData, &p, &n, &plist[0]); // strips out ttp pdu params 63 this->SendCredit = n; 64 this->TxMaxSduSize = 0; 65 //this->MaxSegSize = MaxTxIrLapDataSize - 3; 66 this->MaxSegSize = peerQOS->GetDataSize() - 3; // get max send pkt size 67 68 if (p == 1) { 69 UInt32 value; 70 if (ttp_pdu_connect_get_max_sdu_size(plist, &value)) 71 this->TxMaxSduSize = value; 72 } 73 74 TTPConnectIndication(result, sap, ourQOS, peerQOS, this->TxMaxSduSize, userData); // virtual callback 75 //BufFree(userData); // we'll free up the userData now ... 76 // nope -- this buffer was passed to us in a listen request, let our client free it too. 77} 78 79void 80TTinyTP::TTPHandleConnectConfirm ( 81 TTPSAP sap, // calling TTP SAP 82 TIrQOS *ourQOS, // our QoS 83 TIrQOS *peerQOS, // peer QoS 84 TTPBuf *userData) // calling UserData 85{ 86 unsigned char plist[100]; // enough for me ... 87 int p; // parameters? 88 int n; // initial credit 89 90 XTRACE(kHandleConnectConfirm, 0, 0); 91 92 ttp_pdu_connect_parse(userData, &p, &n, &plist[0]); // strips out ttp pdu params 93 this->SendCredit = n; 94 this->TxMaxSduSize = 0; 95 //this->MaxSegSize = MaxTxIrLapDataSize - 3; 96 this->MaxSegSize = peerQOS->GetDataSize() - 3; // get max send pkt size 97 98 if (p == 1) { 99 UInt32 value; 100 if (ttp_pdu_connect_get_max_sdu_size(plist, &value)) 101 this->TxMaxSduSize = value; 102 XTRACE(kHandleConnectConfirm, 1, value); 103 } 104 105 this->Connected = true; // change state before my callback does more work! 106 107 108 // this is a rather different ... as soon as the TTP session is open, hang a read 109 // on the connection. every time a read completes, pass the buffer up, allocate 110 // a new one, and hang another read out. TTP Client is responsible for eventually 111 // freeing the buffers passed to it via DataIndication(). 112 { CBufferSegment *getBuf; 113 getBuf = BufAlloc(2048+5); // need up to max lap size 114 require(getBuf, NoMem); // not a lot I can do w/out a read buffer 115 this->DataGet(getBuf); // start the read 116 } 117 118 // Now that the read is pending, tell the client .... (was in other order) 119 TTPConnectConfirm(sap, ourQOS, peerQOS, this->TxMaxSduSize, userData); // virtual callback to ttp client 120 BufFree(userData); // free the connect buffer allocated by PDU Connect 121NoMem: 122 return; 123} 124 125void 126TTinyTP::TTPHandleDisconnectIndication ( 127 int reason, // passed up from IrLMP 128 TTPBuf *userData) 129{ 130 XTRACE(kHandleDisconnectIndication, 0, 0); 131 132 this->Connected = false; 133 this->FlushQueue(&(this->TxQueue)); 134 txQDepth = 0; 135 this->AppendTail(&(this->RxQueue), TTP_Disconnect, reason, userData); 136} 137 138void 139TTinyTP::TTPHandleDataIndication ( 140 TTPBuf *userData) // data read 141{ 142 int credit; 143 Boolean m; 144 145 check(userData); 146 { int position, bufsize; 147 position = BufUsed(userData); // should be zero 148 bufsize = BufSize(userData); // amount read 149 XTRACE(kHandleDataIndication, position, bufsize); 150 } 151 152 ttp_pdu_data_parse(userData, &m, &credit); // strips out ttp overhead byte 153 this->SendCredit += credit; 154 if (SendCredit > 30) SendCredit = 30; // FIXME: temp workaround for HP runaway credits 155 // WARNING: HP tells us that Microsoft believes in 156 // extending lots and lots of credits, and relies on 157 // lap-layer flow control to survive. 158 159 if (credit > 0) // if we've been given more credits from IrLan box 160 TTPBackEnable(); // then tell clients flow-control state has changed 161 162 if (BufSize(userData) > 0) { 163 XTRACE(kHandleDataIndication, m, credit); // log what we parsed 164 this->RemoteCredit--; 165 if (m == false) // if no More data 166 this->AppendTail(&(this->RxQueue), TTP_Segment_Last, 0, userData); 167 else // else have More data 168 this->AppendTail(&(this->RxQueue), TTP_Segment, 0, userData); 169 } 170 else { 171 XTRACE(kDataLessPacket, m, credit); // log we received a dataless packet 172 BufFree(userData); // we're done with it now... 173 } 174 175 // Make sure a read is pending at all times .... this could 176 // use a better model. Only post if connected. 177 if( this->Connected ) 178 { CBufferSegment *getBuf; 179 getBuf = BufAlloc(2048+5); // need up to max lap size 180 require(getBuf, NoMem); 181 this->DataGet(getBuf); 182 } 183NoMem: 184 return; 185} 186 187void 188TTinyTP::TTPHandleUDataIndication ( 189 TTPBuf *userData) // data read 190{ 191 //DebugLog("How'd I get here? TTinyTP::HandleUDataIndication"); 192 TTPUDataIndication(userData); 193} 194 195void 196TTinyTP::TTPHandleAcceptComplete(IrDAErr result, TTPBuf *userdata) 197{ 198 check(userdata); 199 BufFree(userdata); // free buffer alloc'd by ttp.c in accept routine 200 TTPAcceptDoneIndication(result); // just result, no buffer, since we copied clients during accept 201} 202 203