Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2193 lines
55 KiB

  1. /*++
  2. Copyright (c) 1996,1997 Microsoft Corporation
  3. Module Name:
  4. RECEIVE.C
  5. Abstract:
  6. Receive Handler and Receive Thread.
  7. Author:
  8. Aaron Ogus (aarono)
  9. Environment:
  10. Win32/COM
  11. Revision History:
  12. Date Author Description
  13. ====== ====== ============================================================
  14. 12/10/96 aarono Original
  15. 02/18/98 aarono Added support for SendEx
  16. 6/6/98 aarono Turn on throttling and windowing
  17. 6/10/98 aarono Allow out of order receives when requested by application
  18. 4/15/99 aarono Take a Send reference in NACK and ACK handlers
  19. --*/
  20. #include <windows.h>
  21. #include "newdpf.h"
  22. #include <dplay.h>
  23. #include <dplaysp.h>
  24. #include <dplaypr.h>
  25. #include "mydebug.h"
  26. #include "arpd.h"
  27. #include "arpdint.h"
  28. #include "protocol.h"
  29. #include "macros.h"
  30. #include "command.h"
  31. // Note: WaitForMultipleObjects has a bug where it restarts the wait in
  32. // the middle of the list and can run off the end. We put an extra
  33. // entry at the end of the object list to deal with this and when
  34. // we get an invalid_handle error, we just re-wait.
  35. // First object is an event that is signalled when
  36. // the wait list needs to be changed.
  37. // Receive List Semantics. The Receive thread
  38. VOID ProcessACK(PPROTOCOL pProtocol, PCMDINFO pCmdInfo);
  39. VOID ProcessNACK(PPROTOCOL pProtocol, PCMDINFO pCmdInfo, PUCHAR pNACKmask, UINT nNACK);
  40. VOID ProcessAbort(PPROTOCOL pProtocol, DPID idFrom, DPID idTo, pABT1 pABT, BOOL fBig);
  41. VOID SendACK(PPROTOCOL pProtocol, PSESSION pSession, PCMDINFO pCmdInfo);
  42. // Function table for received commands.
  43. UINT (*ProtocolFn[MAX_COMMAND+1])(REQUEST_PARAMS)={
  44. AssertMe, // 0x00
  45. Ping, // 0x01
  46. PingResp, // 0x02
  47. GetTime, // 0x03
  48. GetTimeResp, // 0x04
  49. SetTime, // 0x05
  50. SetTimeResp // 0x06
  51. };
  52. VOID FreeReceiveBuffers(PRECEIVE pReceive)
  53. {
  54. BILINK *pBilink;
  55. PBUFFER pBuffer;
  56. pBilink=pReceive->RcvBuffList.next;
  57. while(pBilink != &pReceive->RcvBuffList){
  58. pBuffer=CONTAINING_RECORD(pBilink, BUFFER, BuffList);
  59. pBilink=pBilink->next;
  60. FreeFrameBuffer(pBuffer);
  61. }
  62. }
  63. VOID CopyReceiveBuffers(PRECEIVE pReceive,PVOID pBuffers,UINT nBuffers)
  64. {
  65. #define MemDesc(_i) (*(((PMEMDESC)pBuffers)+(_i)))
  66. PBUFFER pBuffer;
  67. UINT BytesToCopy;
  68. UINT BuffLen;
  69. UINT BuffOffset;
  70. UINT mdlen;
  71. UINT mdoffset;
  72. UINT i=0;
  73. PUCHAR src;
  74. PUCHAR dest;
  75. UINT len;
  76. BytesToCopy=pReceive->MessageSize;
  77. pBuffer=(PBUFFER)pReceive->RcvBuffList.next;
  78. BuffLen=(UINT)(pBuffer->len-(pBuffer->pCmdData-pBuffer->pData));
  79. BuffOffset=0;
  80. mdlen=MemDesc(0).len;
  81. mdoffset=0;
  82. while(BytesToCopy){
  83. if(!mdlen){
  84. i++;
  85. mdlen=MemDesc(i).len;
  86. mdoffset=0;
  87. ASSERT(i<nBuffers);
  88. }
  89. if(!BuffLen){
  90. pBuffer=pBuffer->pNext;
  91. ASSERT(pBuffer);
  92. BuffLen=(UINT)(pBuffer->len-(pBuffer->pCmdData-pBuffer->pData));
  93. BuffOffset=0;
  94. }
  95. src=&pBuffer->pCmdData[BuffOffset];
  96. dest=&(MemDesc(i).pData[mdoffset]);
  97. if(BuffLen > mdlen){
  98. len=mdlen;
  99. BuffOffset+=len;
  100. } else {
  101. len=BuffLen;
  102. mdoffset+=len;
  103. }
  104. DPF(9,"CopyReceiveBuffers src,dest,len: %x %x %x\n",dest,src,len);
  105. memcpy(dest,src,len);
  106. BuffLen-=len;
  107. mdlen-=len;
  108. BytesToCopy-=len;
  109. }
  110. #undef MemDesc
  111. }
  112. HRESULT _inline ParseHeader(
  113. FLAGS *pflags,
  114. PUCHAR pData,
  115. UINT * pCommand,
  116. UINT *piEOF,
  117. UINT *piEOA,
  118. UINT *piEON,
  119. UINT *pnNACK)
  120. {
  121. if(pflags->flag1 & BIG){
  122. // big frame
  123. if(pflags->flag1 & CMD){
  124. // big command frame
  125. if(pflags->flag1 & EXT){
  126. // big command frame with explicit command
  127. *pCommand=pflags->flag2 & ~EXT;
  128. if(pflags->flag2 & EXT){
  129. // big command frame with explicit command and NACK
  130. *pnNACK=pflags->flag3 & ~EXT;
  131. *piEOF=3;
  132. } else {
  133. // big command frame with explicit command, no NACK
  134. *pnNACK=0;
  135. *piEOF=2;
  136. }
  137. } else {
  138. // big -I- frame, no NACK
  139. *pCommand=0;
  140. *pnNACK=0;
  141. *piEOF=1;
  142. }
  143. } else {
  144. // big supervisory (non-command) frame
  145. if(pflags->flag1 & EXT){
  146. // big supervisory frame with nNACK
  147. *pnNACK=pflags->flag2 & ~EXT;
  148. ASSERT(*pnNACK);
  149. *piEOF=2;
  150. } else {
  151. // big supervisory frame with no-nNACK
  152. *pnNACK=0;
  153. *piEOF=1;
  154. }
  155. }
  156. } else {
  157. // small frame
  158. if(pflags->flag1 & CMD){
  159. // small command frame
  160. if(pflags->flag1 & EXT){
  161. // small command frame (with NACK?) and explicit command
  162. DPF(0,"ERROR PARSING FRAME, NOT RECOGNIZED, ABORTING DECODE\n");
  163. return DPERR_ABORTED;
  164. *pCommand = pflags->flag2 & CMD_MSK;
  165. *pnNACK = (pflags->flag2 & nNACK_MSK) >> nNACK_SHIFT;
  166. *piEOF = 2;
  167. } else {
  168. // small -I- frame, no NACK
  169. *pCommand = 0;
  170. *pnNACK = 0;
  171. *piEOF = 1;
  172. }
  173. } else {
  174. // small supervisory (non-command) frame
  175. if(pflags->flag1 & EXT){
  176. *pnNACK = (pflags->flag2 & nNACK_MSK) >> nNACK_SHIFT;
  177. *piEOF = 2;
  178. } else {
  179. *pnNACK=0;
  180. *piEOF=1;
  181. }
  182. }
  183. }
  184. while(pData[(*piEOF)-1]&EXT){
  185. // Skip past any flags extensions we don't understand.
  186. // small command frame (with NACK?) and explicit command
  187. DPF(0,"ERROR PARSING FRAME, NOT RECOGNIZED, ABORTING DECODE\n");
  188. return DPERR_ABORTED;
  189. (*piEOF)++;
  190. }
  191. *piEOA=*piEOF;
  192. // Update any ACK information.
  193. if((pflags->flag1 & ACK)){
  194. if((pflags->flag1 & BIG)){
  195. // LARGE ACK
  196. *piEOA+=sizeof(ACK2);
  197. } else {
  198. // SMALL ACK
  199. *piEOA+=sizeof(ACK1);
  200. }
  201. }
  202. *piEON = *piEOA;
  203. // Update any NACK information.
  204. if(*pnNACK){
  205. if((pflags->flag1 & BIG)){
  206. *piEON+=sizeof(NACK2);
  207. }else{
  208. *piEON+=sizeof(NACK1);
  209. }
  210. *piEON+=*pnNACK;
  211. }
  212. return DP_OK;
  213. }
  214. /*=============================================================================
  215. ProtocolReceive - Receive handler for protocol, called when we've
  216. verified the message is a protocol message and
  217. we've been able to allocate receive space for the
  218. message
  219. Description:
  220. Cracks the protocol header on the message and fills in a CMDINFO
  221. structure to describe the protocol information in the frame. Then
  222. dispatches the message along with the CMDINFO to the appropriate
  223. handler.
  224. A packet may have ACK or NACK information in the header and still
  225. be a command packet. We do ACK/NACK processing first, then we
  226. do command processing.
  227. This routine will dispatch to
  228. ProcessACK
  229. ProcessNACK
  230. CommandReceive
  231. Parameters:
  232. idFrom - index in player table of sending player
  233. idTo - " " receiving player
  234. pBuffer - a buffer we own with a copy of the message
  235. pSPHeader - if present can be used to issue a reply without an id.
  236. Return Values:
  237. None.
  238. Notes:
  239. -----------------------------------------------------------------------------*/
  240. VOID ProtocolReceive(PPROTOCOL pProtocol, WORD idFrom, WORD idTo, PBUFFER pBuffer, PVOID pSPHeader)
  241. {
  242. #define pFrame ((pPacket1)(pBuffer->pData))
  243. #define pBigFrame ((pPacket2)(pBuffer->pData))
  244. #define pACK ((pACK1)(&pData[iEOF]))
  245. #define pBigACK ((pACK2)(&pData[iEOF]))
  246. #define pABT ((pABT1)(&pData[iEOF]))
  247. #define pBigABT ((pABT2)(&pData[iEOF]))
  248. #define pNACK ((pNACK1)(&pData[iEOA]))
  249. #define pBigNACK ((pNACK2)(&pData[iEOA]))
  250. #define pCMD ((pCMD1)(&pData[iEON]))
  251. #define pBigCMD ((pCMD2)(&pData[iEON]))
  252. PUCHAR pData;
  253. FLAGS flags;
  254. UINT command; // the command if a command frame.
  255. UINT nNACK; // if this is a NACK frame, sizeof bitfield
  256. UINT iEOF; // index past end of flags
  257. UINT iEOA; // index past end of any ACK or ABT information
  258. UINT iEON; // index past end of any NACK information
  259. UINT rc=0;
  260. PUCHAR pNACKmask;
  261. HRESULT hr;
  262. CMDINFO CmdInfo;
  263. PCMDINFO pCmdInfo=&CmdInfo;
  264. CmdInfo.tReceived=timeGetTime();
  265. pData=pBuffer->pData;
  266. memcpy(&flags,pData,sizeof(flags));
  267. hr=ParseHeader(&flags, pData, &command, &iEOF, &iEOA, &iEON, &nNACK);
  268. if(hr==DPERR_ABORTED){
  269. goto exit;
  270. }
  271. // Get the DPLAY id's for the indicies
  272. CmdInfo.idFrom = GetDPIDByIndex(pProtocol, idFrom);
  273. if(CmdInfo.idFrom == 0xFFFFFFFF){
  274. DPF(1,"Rejecting packet with invalid From Id\n",idFrom);
  275. goto exit;
  276. }
  277. CmdInfo.idTo = GetDPIDByIndex(pProtocol, idTo);
  278. if(CmdInfo.idTo == 0xFFFFFFFF){
  279. DPF(1,"Rejecting packet with invalid To Id\n");
  280. goto exit;
  281. }
  282. DPF(9,"Protocol Receive idFrom %x idTo %x\n",CmdInfo.idFrom,CmdInfo.idTo);
  283. CmdInfo.wIdFrom = idFrom;
  284. CmdInfo.wIdTo = idTo;
  285. CmdInfo.flags = flags.flag1;
  286. CmdInfo.pSPHeader = pSPHeader;
  287. // determine masks to use for this size frame
  288. if(flags.flag1 & BIG){
  289. IDMSK = 0xFFFF;
  290. SEQMSK = 0xFFFF;
  291. } else {
  292. IDMSK = 0xFF;
  293. SEQMSK = 0xFF;
  294. }
  295. if((flags.flag1 & ACK))
  296. {
  297. // Process the ACK field (could be piggyback).
  298. if(flags.flag1 & BIG){
  299. pCmdInfo->messageid = pBigACK->messageid;
  300. pCmdInfo->sequence = pBigACK->sequence;
  301. pCmdInfo->serial = pBigACK->serial;
  302. pCmdInfo->bytes = pBigACK->bytes;
  303. pCmdInfo->tRemoteACK= pBigACK->time;
  304. } else {
  305. pCmdInfo->messageid = pACK->messageid;
  306. pCmdInfo->sequence = pACK->sequence;
  307. pCmdInfo->serial = pACK->serial;
  308. pCmdInfo->bytes = pACK->bytes;
  309. pCmdInfo->tRemoteACK= pACK->time;
  310. }
  311. DPF(9,"ACK: msgid: %d seq %d serial %d\n",CmdInfo.messageid, CmdInfo.sequence, CmdInfo.serial);
  312. if(CmdInfo.serial==150){
  313. // this is a little excessive for retries, break out so we can debug this.
  314. DPF(0,"ProtocolReceive: WHOOPS, 150 retries is a little excessive\n");
  315. ASSERT(0);
  316. }
  317. ProcessACK(pProtocol, &CmdInfo);
  318. }
  319. if(nNACK){
  320. if(flags.flag1 & BIG){
  321. CmdInfo.messageid = pBigNACK->messageid;
  322. CmdInfo.sequence = pBigNACK->sequence;
  323. CmdInfo.bytes = pBigNACK->bytes;
  324. CmdInfo.tRemoteACK= pBigNACK->time;
  325. pNACKmask = pBigNACK->mask;
  326. } else {
  327. CmdInfo.messageid = pNACK->messageid;
  328. CmdInfo.sequence = pNACK->sequence;
  329. CmdInfo.bytes = pNACK->bytes;
  330. CmdInfo.tRemoteACK= pNACK->time;
  331. pNACKmask = pNACK->mask;
  332. }
  333. DPF(9,"NACK: msgid: %d seq %d\n",CmdInfo.messageid, CmdInfo.sequence);
  334. ProcessNACK(pProtocol, &CmdInfo, pNACKmask, nNACK);
  335. }
  336. #ifdef DEBUG
  337. if((flags.flag1 & ACK) || nNACK)
  338. {
  339. IN_WRITESTATS InWS;
  340. memset((PVOID)&InWS,0xFF,sizeof(IN_WRITESTATS));
  341. InWS.stat_RemBytesReceived=CmdInfo.bytes;
  342. DbgWriteStats(&InWS);
  343. }
  344. #endif
  345. if((flags.flag1 & CMD)){
  346. CmdInfo.command = command;
  347. if((flags.flag1 & BIG)){
  348. CmdInfo.messageid= pBigCMD->messageid;
  349. CmdInfo.sequence = pBigCMD->sequence;
  350. CmdInfo.serial = pBigCMD->serial;
  351. pBuffer->pCmdData = pData+iEON+5;//(+5 for messageid(2), sequence(2), serial(1))
  352. } else {
  353. CmdInfo.messageid= pCMD->messageid;
  354. CmdInfo.sequence = pCMD->sequence;
  355. CmdInfo.serial = pCMD->serial;
  356. pBuffer->pCmdData = pData+iEON+3;//(+3 for byte messageid,seq,serial)
  357. }
  358. rc=CommandReceive(pProtocol, &CmdInfo, pBuffer);
  359. }
  360. if(!rc){
  361. exit:
  362. FreeFrameBuffer(pBuffer);
  363. }
  364. return;
  365. #undef pNACK
  366. #undef pBigNACK
  367. #undef pCMD
  368. #undef pBigCMD
  369. #undef pABT
  370. #undef pBigABT
  371. #undef pACK
  372. #undef pBigACK
  373. #undef pBigFrame
  374. #undef pFrame
  375. }
  376. VOID FreeReceive(PPROTOCOL pProtocol, PRECEIVE pReceive)
  377. {
  378. DPF(9,"Freeing Receive %x\n",pReceive);
  379. FreeReceiveBuffers(pReceive);
  380. ReleaseRcvDesc(pProtocol, pReceive);
  381. }
  382. #ifdef DEBUG
  383. VOID DebugScanForMessageId(BILINK *pBilink, UINT messageid)
  384. {
  385. BILINK *pBilinkWalker;
  386. PRECEIVE pReceive;
  387. pBilinkWalker=pBilink->next;
  388. while(pBilinkWalker!=pBilink){
  389. pReceive=CONTAINING_RECORD(pBilinkWalker,RECEIVE,pReceiveQ);
  390. if(pReceive->messageid==messageid){
  391. DPF(0,"ERROR: MESSAGEID x%x already exists in pReceive %x\n",pReceive);
  392. DEBUG_BREAK();
  393. }
  394. pBilinkWalker=pBilinkWalker->next;
  395. }
  396. }
  397. #else
  398. #define DebugScanForMessageId(_a,_b)
  399. #endif
  400. #ifdef DEBUG
  401. VOID DbgCheckReceiveStart(PSESSION pSession,PRECEIVE pReceive,PBUFFER pBuffer)
  402. {
  403. BILINK *pBilink;
  404. PBUFFER pBuffWalker;
  405. pBilink=pReceive->RcvBuffList.next;
  406. while(pBilink != &pReceive->RcvBuffList){
  407. pBuffWalker=CONTAINING_RECORD(pBilink, BUFFER, BuffList);
  408. pBilink=pBilink->next;
  409. if(pBuffWalker->sequence==1){
  410. break;
  411. }
  412. }
  413. if( ((pBuffer->len-(pBuffer->pCmdData-pBuffer->pData)) != (pBuffWalker->len-(pBuffWalker->pCmdData-pBuffWalker->pData))) ||
  414. (memcmp(pBuffWalker->pCmdData,
  415. pBuffer->pCmdData,
  416. (UINT32)(pBuffer->len-(pBuffer->pCmdData-pBuffer->pData)))) )
  417. {
  418. DPF(0,"Different retry start buffer, pSession %x, pReceive %x, pBufferOnList %x, pBuffer %x\n",pSession,pReceive,pBuffWalker,pBuffer);
  419. DEBUG_BREAK();
  420. }
  421. // compare the buffers
  422. }
  423. #else
  424. #define DbgCheckReceiveStart
  425. #endif
  426. // If a receive is returned, it is locked on behalf of the caller.
  427. /*=============================================================================
  428. GetReceive - for a received data message find the receive structure
  429. or create one. If this message is a retry of a completed
  430. message, send an extra ACK.
  431. Description:
  432. Parameters:
  433. pProtocol
  434. pSession
  435. pCmdInfo
  436. Return Values:
  437. PRECEIVE - pointer to receive for this frame
  438. Notes:
  439. -----------------------------------------------------------------------------*/
  440. PRECEIVE GetReceive(PPROTOCOL pProtocol, PSESSION pSession, PCMDINFO pCmdInfo, PBUFFER pBuffer)
  441. {
  442. #define flags pCmdInfo->flags
  443. BOOL fFoundReceive=FALSE;
  444. BILINK *pBiHead, *pBilink;
  445. PRECEIVE pReceive=NULL,pReceiveWalker;
  446. DPF(9,"==>GetReceive pSession %x\n",pSession);
  447. Lock(&pSession->SessionLock);
  448. // Scan the queue on the SESSION for a RECEIVE with this messageid.
  449. if(flags & RLY){
  450. pBiHead = &pSession->pRlyReceiveQ;
  451. if(!pSession->fReceiveSmall){
  452. IDMSK = 0xFFFF;
  453. }
  454. } else {
  455. pBiHead = &pSession->pDGReceiveQ;
  456. if(!pSession->fReceiveSmallDG){
  457. IDMSK = 0xFFFF;
  458. }
  459. }
  460. pBilink = pBiHead->next;
  461. while(pBilink != pBiHead){
  462. pReceive=CONTAINING_RECORD(pBilink, RECEIVE, pReceiveQ);
  463. ASSERT_SIGN(pReceive, RECEIVE_SIGN);
  464. pBilink=pBilink->next;
  465. if(pReceive->messageid==pCmdInfo->messageid){
  466. Lock(&pReceive->ReceiveLock);
  467. if(!pReceive->fBusy){
  468. ASSERT(pReceive->command == pCmdInfo->command);
  469. ASSERT(pReceive->fReliable == (flags & RLY));
  470. fFoundReceive=TRUE;
  471. break;
  472. } else {
  473. Unlock(&pReceive->ReceiveLock);
  474. // its moving, so its done. Ignore.
  475. // there is probably a racing ACK already so ignore is fine.
  476. DPF(9,"GetReceive: Receive %x for messageid x%x is completing already, so ignoring receive\n",pReceive,pReceive->messageid);
  477. ASSERT(0);
  478. pReceive=NULL;
  479. goto exit;
  480. }
  481. }
  482. }
  483. if(!fFoundReceive){
  484. DPF(9,"GetReceive: Didn't find a receive for messageid x%x\n",pCmdInfo->messageid);
  485. pReceive=NULL;
  486. } else {
  487. DPF(9,"GetReceive: Found receive %x for messageid x%x\n",pReceive, pCmdInfo->messageid);
  488. }
  489. if(pReceive && ( flags & STA )){
  490. // Should get blown away below - this is the start frame, but we already got it
  491. DPF(9,"GetReceive: Got start for receive %x messageid x%x we already have going\n",pReceive, pCmdInfo->messageid);
  492. DbgCheckReceiveStart(pSession,pReceive,pBuffer);
  493. Unlock(&pReceive->ReceiveLock);
  494. pReceive=NULL;
  495. goto ACK_EXIT;
  496. }
  497. if(!pReceive){
  498. if(flags & RLY){
  499. UINT MsgIdDelta;
  500. DWORD bit;
  501. MsgIdDelta=(pCmdInfo->messageid - pSession->FirstRlyReceive)&IDMSK;
  502. bit=MsgIdDelta-1;
  503. if((bit > MAX_LARGE_CSENDS) || (pSession->InMsgMask & (1<<bit))){
  504. DPF(9,"GetReceive: dropping extraneous rexmit data\n");
  505. if(flags & EOM|SAK) {
  506. // RE-ACK the message.
  507. DPF(9,"GetReceive: Sending extra ACK anyway\n");
  508. goto ACK_EXIT;
  509. }
  510. goto exit; // Drop it, this is for an old message.
  511. } else {
  512. // if( (MsgIdDelta==0) ||
  513. // ((pSession->fReceiveSmall)?(MsgIdDelta > MAX_SMALL_CSENDS):(MsgIdDelta > MAX_LARGE_CSENDS))){
  514. // DPF(5,"GetReceive: dropping extraneous rexmit data\n");
  515. // if(flags & EOM|SAK) {
  516. // // RE-ACK the message.
  517. // DPF(5,"GetReceive: Sending extra ACK anyway\n");
  518. // goto ACK_EXIT;
  519. // }
  520. // goto exit; // Drop it, this is for an old message.
  521. // } else {
  522. if(flags & STA){
  523. if(pSession->LastRlyReceive==pCmdInfo->messageid){
  524. DPF(9,"RECEIVE: dropping resend for messageid x%x, but ACKING\n",pCmdInfo->messageid);
  525. // RE-ACK the message.
  526. goto ACK_EXIT;
  527. }
  528. if(((pSession->LastRlyReceive-pSession->FirstRlyReceive)&IDMSK)<MsgIdDelta){
  529. pSession->LastRlyReceive=pCmdInfo->messageid;
  530. DPF(9,"GetReceive: New messageid x%x FirstRcv %x LastRcv %x\n",pCmdInfo->messageid,pSession->FirstRlyReceive,pSession->LastRlyReceive);
  531. #ifdef DEBUG
  532. if(!pSession->fReceiveSmall){
  533. if(((pSession->LastRlyReceive-pSession->FirstRlyReceive) & 0xFFFF) > MAX_LARGE_CSENDS){
  534. ASSERT(0);
  535. }
  536. } else {
  537. if(((pSession->LastRlyReceive-pSession->FirstRlyReceive) & 0x0FF) > MAX_SMALL_CSENDS){
  538. ASSERT(0);
  539. }
  540. }
  541. #endif
  542. }
  543. }
  544. }
  545. } else {
  546. // Nonreliable, blow away any messages outside the window.
  547. // also blow away any residual messages with same number if we are a START.
  548. pBiHead = &pSession->pDGReceiveQ;
  549. pBilink = pBiHead->next;
  550. while( pBilink != pBiHead ){
  551. pReceiveWalker=CONTAINING_RECORD(pBilink, RECEIVE, pReceiveQ);
  552. ASSERT_SIGN(pReceiveWalker, RECEIVE_SIGN);
  553. pBilink=pBilink->next;
  554. if(!pReceiveWalker->fBusy &&
  555. ( (((pCmdInfo->messageid - pReceiveWalker->messageid) & IDMSK ) > ((pSession->fReceiveSmallDG)?(MAX_SMALL_DG_CSENDS):(MAX_LARGE_DG_CSENDS))) ||
  556. ((flags&STA) && pCmdInfo->messageid==pReceiveWalker->messageid)
  557. )
  558. ){
  559. Lock(&pReceiveWalker->ReceiveLock);
  560. if(!pReceiveWalker->fBusy){
  561. DPF(9,"GetReceive: Got Id %d Throwing Out old Datagram Receive id %d\n",pCmdInfo->messageid,pReceiveWalker->messageid);
  562. Delete(&pReceiveWalker->pReceiveQ);
  563. Unlock(&pReceiveWalker->ReceiveLock);
  564. FreeReceive(pProtocol,pReceiveWalker);
  565. } else {
  566. ASSERT(0);
  567. DPF(0,"GetReceive: Got Id %d Couldn't throw out DG id %d\n",pCmdInfo->messageid,pReceiveWalker->messageid);
  568. Unlock(&pReceiveWalker->ReceiveLock);
  569. }
  570. }
  571. }
  572. }
  573. // Allocate a receive structure
  574. if(flags & STA){
  575. pReceive=GetRcvDesc(pProtocol);
  576. DPF(9,"allocated new receive %x messageid x%x\n",pReceive,pCmdInfo->messageid);
  577. if(!pReceive){
  578. // no memory, drop it.
  579. ASSERT(0);
  580. DPF(0,"RECEIVE: no memory! dropping packet\n");
  581. goto exit;
  582. }
  583. pReceive->pSession = pSession;
  584. pReceive->fBusy = FALSE;
  585. pReceive->fReliable = flags&RLY;
  586. pReceive->fEOM = FALSE;
  587. pReceive->command = pCmdInfo->command;
  588. pReceive->messageid = pCmdInfo->messageid;
  589. pReceive->iNR = 0;
  590. pReceive->NR = 0;
  591. pReceive->NS = 0;
  592. pReceive->RCVMask = 0;
  593. pReceive->MessageSize = 0;
  594. InitBilink(&pReceive->RcvBuffList);
  595. Lock(&pReceive->ReceiveLock);
  596. if(flags & RLY){
  597. // Set bit in incoming receive mask;
  598. DebugScanForMessageId(&pSession->pRlyReceiveQ, pCmdInfo->messageid);
  599. InsertAfter(&pReceive->pReceiveQ,&pSession->pRlyReceiveQ);
  600. } else {
  601. DebugScanForMessageId(&pSession->pDGReceiveQ, pCmdInfo->messageid);
  602. InsertAfter(&pReceive->pReceiveQ,&pSession->pDGReceiveQ);
  603. }
  604. // Save the SP header for indications
  605. if(pCmdInfo->pSPHeader){
  606. pReceive->pSPHeader=&pReceive->SPHeader[0];
  607. memcpy(pReceive->pSPHeader, pCmdInfo->pSPHeader, pProtocol->m_dwSPHeaderSize);
  608. } else {
  609. pReceive->pSPHeader=NULL;
  610. }
  611. }
  612. }
  613. exit:
  614. Unlock(&pSession->SessionLock);
  615. unlocked_exit:
  616. DPF(9,"<==GetReceive pSession %x pReceive %x\n",pSession, pReceive);
  617. return pReceive;
  618. #undef flags
  619. ACK_EXIT:
  620. Unlock(&pSession->SessionLock);
  621. SendACK(pProtocol,pSession,pCmdInfo);
  622. goto unlocked_exit;
  623. }
  624. VOID PutBufferOnReceive(PRECEIVE pReceive, PBUFFER pBuffer)
  625. {
  626. BILINK *pBilink;
  627. PBUFFER pBuffWalker;
  628. pBilink=pReceive->RcvBuffList.prev;
  629. while(pBilink != &pReceive->RcvBuffList){
  630. pBuffWalker=CONTAINING_RECORD(pBilink, BUFFER, BuffList);
  631. #ifdef DEBUG
  632. if(pBuffWalker->sequence==pBuffer->sequence){
  633. DPF(0,"already have sequence queued?\n");
  634. DEBUG_BREAK();
  635. break;
  636. }
  637. #endif
  638. if(pBuffWalker->sequence < pBuffer->sequence){
  639. break;
  640. }
  641. pBilink=pBilink->prev;
  642. }
  643. InsertAfter(&pBuffer->BuffList, pBilink);
  644. }
  645. // Chains receives that must be also be completed on this Receive
  646. VOID ChainReceiveFromQueue(PSESSION pSession, PRECEIVE pReceive, UINT messageid)
  647. {
  648. BOOL bFound=FALSE;
  649. BILINK *pBilink;
  650. PRECEIVE pReceiveWalker;
  651. DPF(9,"==>ChainReceiveFromQueue on pReceive %x, chain messageid x%x\n",pReceive,messageid);
  652. ASSERT(messageid!=pReceive->messageid);
  653. ASSERT(!EMPTY_BILINK(&pSession->pRlyWaitingQ));
  654. pBilink=pSession->pRlyWaitingQ.next;
  655. while(pBilink != &pSession->pRlyWaitingQ){
  656. pReceiveWalker=CONTAINING_RECORD(pBilink, RECEIVE, pReceiveQ);
  657. if(pReceiveWalker->messageid==messageid){
  658. bFound=TRUE;
  659. break;
  660. }
  661. pBilink=pBilink->next;
  662. }
  663. if(bFound){
  664. // store in order on pReceive->pReceiveQ
  665. Delete(&pReceiveWalker->pReceiveQ);
  666. InsertBefore(&pReceiveWalker->pReceiveQ,&pReceive->pReceiveQ);
  667. DPF(9,"<==ChainReceiveFromQueue: Chained pReceiveWalker %x messageid x%x on pReceive %x\n",pReceiveWalker, pReceiveWalker->messageid, pReceive);
  668. } else {
  669. #ifdef DEBUG
  670. DPF(9,"<==ChainReceiveFromQueue, messageid x%x NOT FOUND!!!, Maybe out of order receive\n",messageid);
  671. if(!(pSession->pProtocol->m_lpDPlay->dwFlags & DPLAYI_DPLAY_PROTOCOLNOORDER)){
  672. DPF(0,"<==ChainReceiveFromQueue, messageid x%x NOT FOUND!!!, NOT ALLOWED with PRESERVE ORDER\n",messageid);
  673. DEBUG_BREAK();
  674. }
  675. #endif
  676. }
  677. }
  678. VOID BlowAwayOldReceives(PSESSION pSession, DWORD messageid, DWORD MASK)
  679. {
  680. BOOL fFoundReceive=FALSE;
  681. BILINK *pBiHead, *pBilink;
  682. PRECEIVE pReceive=NULL;
  683. pBiHead = &pSession->pRlyReceiveQ;
  684. pBilink = pBiHead->next;
  685. while(pBilink != pBiHead){
  686. pReceive=CONTAINING_RECORD(pBilink, RECEIVE, pReceiveQ);
  687. ASSERT_SIGN(pReceive, RECEIVE_SIGN);
  688. pBilink=pBilink->next;
  689. if((int)((pReceive->messageid-messageid)&MASK) <= 0){
  690. Lock(&pReceive->ReceiveLock);
  691. if(!pReceive->fBusy){
  692. DPF(8,"Blowing away duplicate receive %x id\n",pReceive, pReceive->messageid);
  693. Delete(&pReceive->pReceiveQ);
  694. Unlock(&pReceive->ReceiveLock);
  695. FreeReceive(pSession->pProtocol, pReceive);
  696. } else {
  697. DPF(0,"Huston, we have a problem pSession %x, pReceive %x, messageid %d\n",pSession,pReceive,messageid);
  698. DEBUG_BREAK();
  699. Unlock(&pReceive->ReceiveLock);
  700. }
  701. }
  702. }
  703. }
  704. // called with receive lock held, SESSIONion lock unheld,
  705. // returns with receivelock unheld, but receive not on any lists.
  706. // 0xFFFFFFFF means receive was bogus and blown away
  707. UINT DeQueueReceive(PSESSION pSession, PRECEIVE pReceive, PCMDINFO pCmdInfo)
  708. {
  709. UINT bit;
  710. UINT nComplete=0;
  711. DPF(9,"==>DQReceive pReceive %x, messageid x%x\n",pReceive, pReceive->messageid);
  712. pReceive->fBusy=TRUE;
  713. Unlock(&pReceive->ReceiveLock);
  714. Lock(&pSession->SessionLock);
  715. Lock(&pReceive->ReceiveLock);
  716. // Pull off of receive Q
  717. Delete(&pReceive->pReceiveQ);
  718. InitBilink(&pReceive->pReceiveQ); // so we can chain on here.
  719. pReceive->fBusy=FALSE;
  720. bit=((pReceive->messageid-pSession->FirstRlyReceive)&IDMSK)-1;
  721. if(bit >= MAX_LARGE_CSENDS){
  722. // Duplicate receive, blow it away
  723. Unlock(&pReceive->ReceiveLock);
  724. FreeReceive(pSession->pProtocol,pReceive);
  725. Unlock(&pSession->SessionLock);
  726. return 0xFFFFFFFF;
  727. }
  728. #ifdef DEBUG
  729. if(pSession->InMsgMask > (UINT)((1<<((pSession->LastRlyReceive-pSession->FirstRlyReceive)&IDMSK))-1)){
  730. DPF(0,"Bad InMsgMask %x pSession %x\n", pSession->InMsgMask, pSession);
  731. DEBUG_BREAK();
  732. }
  733. #endif
  734. pSession->InMsgMask |= 1<<bit;
  735. while(pSession->InMsgMask&1){
  736. nComplete++;
  737. pSession->FirstRlyReceive=(pSession->FirstRlyReceive+1)&IDMSK;
  738. BlowAwayOldReceives(pSession, pSession->FirstRlyReceive,IDMSK);
  739. if(nComplete > 1){
  740. // Chain extra receives to be indicated on this receive.
  741. ChainReceiveFromQueue(pSession, pReceive,pSession->FirstRlyReceive);
  742. }
  743. pSession->InMsgMask>>=1;
  744. }
  745. #ifdef DEBUG
  746. DPF(9,"DQ: FirstRcv %x LastRcv %x\n",pSession->FirstRlyReceive,pSession->LastRlyReceive);
  747. if((pSession->LastRlyReceive-pSession->FirstRlyReceive & IDMSK) > MAX_LARGE_CSENDS){
  748. DEBUG_BREAK();
  749. }
  750. #endif
  751. Unlock(&pReceive->ReceiveLock);
  752. Unlock(&pSession->SessionLock);
  753. DPF(9,"<==DQReceive pReceive %x nComplete %d\n",pReceive,nComplete);
  754. return nComplete;
  755. }
  756. // called with receive lock held, SESSIONion lock unheld,
  757. // returns with receivelock unheld, but receive not on any lists.
  758. VOID DGDeQueueReceive(PSESSION pSession, PRECEIVE pReceive)
  759. {
  760. pReceive->fBusy=TRUE;
  761. Unlock(&pReceive->ReceiveLock);
  762. Lock(&pSession->SessionLock);
  763. Lock(&pReceive->ReceiveLock);
  764. // Pull off of receive Q
  765. Delete(&pReceive->pReceiveQ);
  766. InitBilink(&pReceive->pReceiveQ);
  767. pReceive->fBusy=FALSE;
  768. Unlock(&pReceive->ReceiveLock);
  769. Unlock(&pSession->SessionLock);
  770. }
  771. #ifdef DEBUG
  772. VOID CheckWaitingQ(PSESSION pSession, PRECEIVE pReceive, PCMDINFO pCmdInfo)
  773. {
  774. BILINK *pBilink;
  775. PRECEIVE pReceiveWalker;
  776. UINT iReceiveWalker;
  777. UINT iReceive; // our index based on FirstRlyReceive
  778. DPF(9,"==>Check WaitingQ\n");
  779. Lock(&pSession->SessionLock);
  780. iReceive=(pReceive->messageid-pSession->FirstRlyReceive)&IDMSK;
  781. pBilink=pSession->pRlyWaitingQ.next;
  782. while(pBilink != &pSession->pRlyWaitingQ){
  783. pReceiveWalker=CONTAINING_RECORD(pBilink, RECEIVE, pReceiveQ);
  784. iReceiveWalker=(pReceiveWalker->messageid-pSession->FirstRlyReceive)&IDMSK;
  785. if((int)iReceiveWalker < 0){
  786. DEBUG_BREAK();
  787. }
  788. if(iReceiveWalker == iReceive){
  789. DPF(9,"Found Duplicate Receive index %d on WaitingQ %x pSession %x\n",iReceiveWalker, &pSession->pRlyWaitingQ, pSession);
  790. // found our insert point.
  791. break;
  792. }
  793. pBilink=pBilink->next;
  794. }
  795. Unlock(&pSession->SessionLock);
  796. DPF(9,"<==CheckWaitingQ\n");
  797. }
  798. #else
  799. #define CheckWaitingQ
  800. #endif
  801. #ifdef DEBUG
  802. VOID DUMPBYTES(PCHAR pBytes, DWORD nBytes)
  803. {
  804. CHAR Target[16];
  805. INT i;
  806. i=0;
  807. while(nBytes){
  808. memset(Target,0,16);
  809. if(nBytes > 16){
  810. memcpy(Target,pBytes+i*16,16);
  811. nBytes-=16;
  812. } else {
  813. memcpy(Target,pBytes+i*16,nBytes);
  814. nBytes=0;
  815. }
  816. DPF(9,"%04x: %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x\n", i*16,
  817. Target[0],Target[1],Target[2],Target[3],Target[4],Target[5],Target[6],Target[7],
  818. Target[8],Target[9],Target[10],Target[11],Target[12],Target[13],Target[14],Target[15]);
  819. i++;
  820. }
  821. }
  822. #else
  823. #define DUMPBYTES(a,b)
  824. #endif
  825. // Out of order reliable message, queue it up on the session.
  826. VOID QueueReceive(PPROTOCOL pProtocol, PSESSION pSession, PRECEIVE pReceive, PCMDINFO pCmdInfo)
  827. {
  828. BILINK *pBilink;
  829. PRECEIVE pReceiveWalker;
  830. UINT iReceiveWalker;
  831. UINT iReceive; // our index based on FirstRlyReceive
  832. DPF(9,"==>QueueReceive Out of order pReceive %x messageid x%x\n",pReceive,pReceive->messageid);
  833. Lock(&pSession->SessionLock);
  834. // Don't need the receive lock since receive already dequeued.
  835. // insert the receive into the pRlyWaitingQ, in order -
  836. // based pSession->FirstRlyReceive IDMSK
  837. // list is ordered left to right, scan from end for our slot.
  838. CheckWaitingQ(pSession, pReceive, pCmdInfo);
  839. iReceive=(pReceive->messageid-pSession->FirstRlyReceive)&IDMSK;
  840. pBilink=pSession->pRlyWaitingQ.prev;
  841. while(pBilink != &pSession->pRlyWaitingQ){
  842. pReceiveWalker=CONTAINING_RECORD(pBilink, RECEIVE, pReceiveQ);
  843. iReceiveWalker=(pReceiveWalker->messageid-pSession->FirstRlyReceive)&IDMSK;
  844. if((int)iReceiveWalker < 0){
  845. DEBUG_BREAK();
  846. }
  847. if(iReceiveWalker < iReceive){
  848. // found our insert point.
  849. break;
  850. }
  851. pBilink=pBilink->prev;
  852. }
  853. // insert in the list.
  854. InsertAfter(&pReceive->pReceiveQ,pBilink);
  855. Unlock(&pSession->SessionLock);
  856. DPF(9,"<==QueueReceive Out of order pReceive\n");
  857. }
  858. VOID IndicateReceive(PPROTOCOL pProtocol, PSESSION pSession, PRECEIVE pReceive, UINT nToIndicate)
  859. {
  860. PDOUBLEBUFFER pDoubleBuffer;
  861. MEMDESC memdesc;
  862. BILINK *pBilink, *pBilinkAnchor;
  863. PRECEIVE pReceiveWalker;
  864. DPF(9,"==>IndicateReceive pReceive %x nToIndicate %d\n",pReceive,nToIndicate);
  865. pBilink=pBilinkAnchor=&pReceive->pReceiveQ;
  866. do{
  867. pReceiveWalker=CONTAINING_RECORD(pBilink, RECEIVE, pReceiveQ);
  868. // Assemble the message into one frame (if it isn't already)
  869. if(pReceiveWalker->iNR==1){
  870. // one frame.
  871. BILINK *pBilink;
  872. PBUFFER pBuffer;
  873. pBilink=pReceiveWalker->RcvBuffList.next;
  874. pBuffer=CONTAINING_RECORD(pBilink, BUFFER, BuffList);
  875. LEAVE_DPLAY();
  876. DPF(9,"Single Indicating pReceive %x messageid x%x\n",pReceiveWalker, pReceiveWalker->messageid);
  877. DUMPBYTES(pBuffer->pCmdData, min((UINT32)(pBuffer->len-(pBuffer->pCmdData-pBuffer->pData)),48));
  878. InternalHandleMessage(pProtocol->m_lpISP,
  879. pBuffer->pCmdData,
  880. (ULONG32)(pBuffer->len-(pBuffer->pCmdData-pBuffer->pData)),
  881. pReceiveWalker->pSPHeader,0);
  882. ENTER_DPLAY();
  883. } else {
  884. // multiple frames, copy to a contiguous chunk.
  885. pDoubleBuffer=GetDoubleBuffer(pReceiveWalker->MessageSize);
  886. if(pDoubleBuffer){
  887. memdesc.pData=pDoubleBuffer->pData;
  888. memdesc.len=pDoubleBuffer->len;
  889. CopyReceiveBuffers(pReceiveWalker,&memdesc,1);
  890. LEAVE_DPLAY();
  891. DPF(9,"Multi Indicating pReceive %x messageid x%x\n",pReceiveWalker, pReceiveWalker->messageid);
  892. DUMPBYTES(memdesc.pData, min(memdesc.len,48));
  893. InternalHandleMessage(pProtocol->m_lpISP,
  894. memdesc.pData,
  895. memdesc.len,
  896. pReceiveWalker->pSPHeader,0);
  897. ENTER_DPLAY();
  898. FreeDoubleBuffer((PBUFFER)pDoubleBuffer);
  899. } else {
  900. DPF(0,"NO MEMORY, MESSAGE DROPPED!\n");
  901. ASSERT(0);
  902. }
  903. }
  904. pBilink=pBilink->next;
  905. FreeReceive(pProtocol, pReceiveWalker);
  906. } while (pBilink != pBilinkAnchor);
  907. DPF(9,"<==IndicateReceive\n");
  908. }
  909. // called with receive lock held, must release
  910. int ReliableAccept(PPROTOCOL pProtocol, PSESSION pSession, PRECEIVE pReceive, PCMDINFO pCmdInfo, PBUFFER pBuffer)
  911. {
  912. int rc=0,rc2;
  913. UINT sequence;
  914. UINT bit;
  915. UINT bitmask;
  916. UINT nToIndicate;
  917. // if its moving, we already have all the data, so drop this.(BUGBUG: maybe ACK again?)
  918. if(!pReceive->fBusy){
  919. bit=(pCmdInfo->sequence-pReceive->NR-1 ) & SEQMSK;
  920. if(bit < 32){
  921. // Calculate absolute sequence number of this packet.
  922. pBuffer->sequence = sequence = (bit+1) + pReceive->iNR;
  923. bitmask=1<<bit;
  924. if((pReceive->RCVMask & bitmask)){
  925. rc=FALSE; // already got this one - reject.
  926. } else {
  927. // Accept it.
  928. PutBufferOnReceive(pReceive,pBuffer);
  929. pReceive->MessageSize+=(UINT)((pBuffer->pData+pBuffer->len)-pBuffer->pCmdData);
  930. pReceive->RCVMask |= bitmask;
  931. if( ((pReceive->NS-pReceive->NR)&SEQMSK) <= bit){
  932. pReceive->NS=(pReceive->NR+bit+1)&SEQMSK;
  933. }
  934. // update NR based on set received bits.
  935. while(pReceive->RCVMask & 1){
  936. pReceive->RCVMask >>= 1;
  937. pReceive->iNR++;
  938. pReceive->NR=(pReceive->NR+1)&SEQMSK;
  939. }
  940. DPF(9,"Reliable ACCEPT: pReceive %x messageid %x iNR %8x NR %2x, NS %2x RCVMask %8x, SEQMSK %2x\n",pReceive, pReceive->messageid, pReceive->iNR, pReceive->NR,pReceive->NS,pReceive->RCVMask,SEQMSK);
  941. rc=TRUE; // packet accepted.
  942. }
  943. } else {
  944. DPF(9,"Reliable ACCEPT: Rejecting Packet Seq %x, NR %x, SEQMSK %x\n",pCmdInfo->sequence, pReceive->NR, SEQMSK);
  945. }
  946. if(pCmdInfo->flags & (SAK|EOM)) {
  947. //ACKrc=SendAppropriateResponse, check code, if ACK on EOM, then POST receive.
  948. rc2=SendAppropriateResponse(pProtocol, pSession, pCmdInfo, pReceive);
  949. if(pCmdInfo->flags & EOM){
  950. if(rc2==SAR_ACK){
  951. goto ReceiveDone;
  952. } else {
  953. pReceive->fEOM=TRUE;
  954. }
  955. } else if(pReceive->fEOM){
  956. if(!pReceive->RCVMask){
  957. goto ReceiveDone;
  958. }
  959. }
  960. }
  961. } else {
  962. ASSERT(0);
  963. }
  964. Unlock(&pReceive->ReceiveLock);
  965. return rc;
  966. ReceiveDone:
  967. DPF(9,"++>ReceiveDone\n");
  968. if(nToIndicate=DeQueueReceive(pSession, pReceive, pCmdInfo)){ // unlocks pReceive->ReceiveLock
  969. if(nToIndicate != 0xFFFFFFFF){
  970. IndicateReceive(pProtocol, pSession, pReceive, nToIndicate);
  971. }
  972. } else if(pProtocol->m_lpDPlay->dwFlags & DPLAYI_DPLAY_PROTOCOLNOORDER){
  973. // Out of order receives are OK
  974. IndicateReceive(pProtocol, pSession, pReceive, 1);
  975. } else {
  976. QueueReceive(pProtocol,pSession,pReceive, pCmdInfo);
  977. }
  978. DPF(9,"<--ReceiveDone\n");
  979. return rc;
  980. }
  981. // Returns highest order byte in n with set bits.
  982. UINT SetBytes(UINT n)
  983. {
  984. UINT nr;
  985. if(n==(n&0xFFFF)){
  986. if(n==(n&0xFF)){
  987. nr=1;
  988. } else {
  989. nr=2;
  990. }
  991. } else {
  992. if(n==(n&0xFFFFFF)){
  993. nr=3;
  994. } else {
  995. nr=4;
  996. }
  997. }
  998. return nr;
  999. }
  1000. VOID InternalSendComplete(PVOID Context, UINT Status)
  1001. {
  1002. PSEND pSend=(PSEND)Context;
  1003. if(pSend->dwFlags & ASEND_PROTOCOL){
  1004. // nothing to do?
  1005. } else if(pSend->bSendEx){
  1006. // send completion if required
  1007. if(pSend->dwFlags & DPSEND_ASYNC){
  1008. DP_SP_SendComplete(pSend->pProtocol->m_lpISP, pSend->lpvUserMsgID, Status);
  1009. }
  1010. }
  1011. }
  1012. // Used by internal routines for sending.
  1013. VOID FillInAndSendBuffer(
  1014. PPROTOCOL pProtocol,
  1015. PSESSION pSession,
  1016. PSEND pSend,
  1017. PBUFFER pBuffer,
  1018. PCMDINFO pCmdInfo)
  1019. {
  1020. pSend->pMessage = pBuffer;
  1021. pSend->MessageSize = pBuffer->len;
  1022. pSend->pSession = pSession;
  1023. pSend->SendOffset = 0;
  1024. pSend->pCurrentBuffer = pBuffer;
  1025. pSend->CurrentBufferOffset = 0;
  1026. pSend->RefCount = 0;
  1027. pSend->pProtocol = pProtocol;
  1028. pSend->dwMsgID = 0;
  1029. pSend->bSendEx = FALSE;
  1030. // pSend->BytesThisSend = 0;
  1031. // Internal sends MUST be highest pri - else can deadlock head to head.
  1032. pSend->Priority = 0xFFFFFFFF;
  1033. pSend->dwFlags = ASEND_PROTOCOL;
  1034. pSend->dwTimeOut = 0;
  1035. pSend->pAsyncInfo = 0;
  1036. pSend->AsyncInfo.hEvent = 0;
  1037. pSend->AsyncInfo.SendCallBack = InternalSendComplete;
  1038. pSend->AsyncInfo.CallBackContext = pSend;
  1039. pSend->AsyncInfo.pStatus = &pSend->Status;
  1040. pSend->SendState = Start;
  1041. pSend->RetryCount = 0;
  1042. pSend->PacketSize = pSession->MaxPacketSize;
  1043. pSend->NR = 0;
  1044. pSend->NS = 0;
  1045. pSend->idFrom = pCmdInfo->idTo;
  1046. pSend->idTo = pCmdInfo->idFrom;
  1047. pSend->wIdTo = pCmdInfo->wIdFrom;
  1048. pSend->serial = 0;
  1049. ISend(pProtocol,pSession,pSend);
  1050. }
  1051. UINT WrapBuffer(PPROTOCOL pProtocol, PCMDINFO pCmdInfo, PBUFFER pBuffer)
  1052. {
  1053. PUCHAR pMessage,pMessageStart;
  1054. DWORD dwWrapSize=0;
  1055. DWORD dwIdTo=0;
  1056. DWORD dwIdFrom=0;
  1057. pMessageStart = &pBuffer->pData[pProtocol->m_dwSPHeaderSize];
  1058. pMessage = pMessageStart;
  1059. dwIdFrom = pCmdInfo->wIdTo;
  1060. dwIdTo = pCmdInfo->wIdFrom;
  1061. if(dwIdFrom==0x70){ // avoid looking like a system message 'play'
  1062. dwIdFrom=0xFFFF;
  1063. }
  1064. if(dwIdFrom){
  1065. while(dwIdFrom){
  1066. *pMessage=(UCHAR)(dwIdFrom & 0x7F);
  1067. dwIdFrom >>= 7;
  1068. if(dwIdFrom){
  1069. *pMessage|=0x80;
  1070. }
  1071. pMessage++;
  1072. }
  1073. } else {
  1074. *(pMessage++)=0;
  1075. }
  1076. if(dwIdTo){
  1077. while(dwIdTo){
  1078. *pMessage=(UCHAR)(dwIdTo & 0x7F);
  1079. dwIdTo >>= 7;
  1080. if(dwIdTo){
  1081. *pMessage|=0x80;
  1082. }
  1083. pMessage++;
  1084. }
  1085. } else {
  1086. *(pMessage++)=0;
  1087. }
  1088. return (UINT)(pMessage-pMessageStart);
  1089. }
  1090. UINT SendAppropriateResponse(PPROTOCOL pProtocol, PSESSION pSession, PCMDINFO pCmdInfo, PRECEIVE pReceive)
  1091. {
  1092. #define pBigACK ((pACK2)pACK)
  1093. #define pBigNACK ((pNACK2)pNACK)
  1094. UINT rc=SAR_FAIL;
  1095. PSEND pSend;
  1096. PBUFFER pBuffer;
  1097. pFLAGS pFlags;
  1098. pACK1 pACK;
  1099. pNACK1 pNACK;
  1100. UINT RCVMask;
  1101. UINT WrapSize;
  1102. // BUGBUG: piggyback ACK on pending send if available.
  1103. pSend=GetSendDesc();
  1104. if(!pSend){
  1105. goto exit1;
  1106. }
  1107. pBuffer = GetFrameBuffer(pProtocol->m_dwSPHeaderSize+MAX_SYS_HEADER);
  1108. if(!pBuffer){
  1109. goto exit2; // out of memory, bail
  1110. }
  1111. WrapSize = pProtocol->m_dwSPHeaderSize;
  1112. WrapSize += WrapBuffer(pProtocol, pCmdInfo, pBuffer);
  1113. pFlags=(pFLAGS)&pBuffer->pData[WrapSize];
  1114. // See if we need to ACK or NACK.
  1115. if(pReceive->RCVMask){
  1116. UINT nNACK=SetBytes(pReceive->RCVMask);
  1117. rc=SAR_NACK;
  1118. // Send a NACK
  1119. if(pCmdInfo->flags & BIG){
  1120. // BIG HEADER FORMAT NACK
  1121. pNACK=(pNACK1)(&pFlags->flag3);
  1122. pFlags->flag1 = EXT|BIG|RLY;
  1123. pFlags->flag2 = (byte)nNACK;
  1124. pBigNACK->sequence = (word)pReceive->NR;
  1125. pBigNACK->messageid = (word)pReceive->messageid;
  1126. pBigNACK->time = pCmdInfo->tReceived;
  1127. pBigNACK->bytes = pSession->LocalBytesReceived;
  1128. RCVMask=pReceive->RCVMask;
  1129. memcpy(&pBigNACK->mask, &RCVMask, nNACK);
  1130. pBuffer->len=WrapSize+2+sizeof(NACK2)+nNACK; //2 for flags
  1131. } else {
  1132. // SMALL HEADER FORMAT NACK
  1133. pNACK=(pNACK1)(&pFlags->flag3);
  1134. pFlags->flag1 = EXT|RLY;
  1135. ASSERT(nNACK < 4);
  1136. ASSERT(pReceive->NR < 32);
  1137. pFlags->flag2 = nNACK << nNACK_SHIFT;
  1138. pNACK->messageid=(byte)pReceive->messageid;
  1139. pNACK->sequence=(byte)pReceive->NR;
  1140. pNACK->time = pCmdInfo->tReceived;
  1141. pNACK->bytes = pSession->LocalBytesReceived;
  1142. RCVMask=pReceive->RCVMask;
  1143. memcpy(&pNACK->mask, &RCVMask, nNACK);
  1144. pBuffer->len=WrapSize+2+sizeof(NACK1)+nNACK; // 2 for flags
  1145. DPF(9,"RcvMask %x Send Appropriate response nNACK=%d\n",pReceive->RCVMask,nNACK);
  1146. }
  1147. } else {
  1148. // Send an ACK
  1149. rc=SAR_ACK;
  1150. pACK = (pACK1)(&pFlags->flag2);
  1151. if(pCmdInfo->flags & BIG){
  1152. // Big packet
  1153. pFlags->flag1 = ACK|BIG;
  1154. pBigACK->messageid= (word)pReceive->messageid;
  1155. pBigACK->sequence = pCmdInfo->sequence;
  1156. pBigACK->serial = pCmdInfo->serial;
  1157. pBigACK->time = pCmdInfo->tReceived;
  1158. pBigACK->bytes = pSession->LocalBytesReceived;
  1159. pBuffer->len = sizeof(ACK2)+1+WrapSize;
  1160. } else {
  1161. // Small packet
  1162. pFlags->flag1 = ACK;
  1163. pACK->messageid = (byte)pReceive->messageid;
  1164. pACK->sequence = (UCHAR)pCmdInfo->sequence;
  1165. pACK->serial = pCmdInfo->serial;
  1166. pACK->time = pCmdInfo->tReceived;
  1167. pACK->bytes = pSession->LocalBytesReceived;
  1168. pBuffer->len = sizeof(ACK1)+1+WrapSize;
  1169. DPF(9,"RcvMask %x Send Appropriate response ACK seq=%x\n",pReceive->RCVMask,pACK->sequence);
  1170. }
  1171. }
  1172. pFlags->flag1 |= (pCmdInfo->flags & RLY);
  1173. FillInAndSendBuffer(pProtocol,pSession,pSend,pBuffer,pCmdInfo);
  1174. exit1:
  1175. return rc;
  1176. exit2:
  1177. ReleaseSendDesc(pSend);
  1178. return rc;
  1179. #undef pBigACK
  1180. #undef pBigNACK
  1181. }
  1182. // ACKs CmdInfo packet.
  1183. VOID SendACK(PPROTOCOL pProtocol, PSESSION pSession, PCMDINFO pCmdInfo)
  1184. {
  1185. #define pBigACK ((pACK2)pACK)
  1186. PSEND pSend;
  1187. PBUFFER pBuffer;
  1188. pFLAGS pFlags;
  1189. pACK1 pACK;
  1190. UINT WrapSize;
  1191. // BUGBUG: piggyback ACK on pending send if available.
  1192. pSend=GetSendDesc();
  1193. if(!pSend){
  1194. goto exit1;
  1195. }
  1196. // allocation here is bigger than necessary but should
  1197. // recyle ACK/NACK buffers.
  1198. pBuffer = GetFrameBuffer(pProtocol->m_dwSPHeaderSize+MAX_SYS_HEADER);
  1199. if(!pBuffer){
  1200. goto exit2; // out of memory, bail
  1201. }
  1202. WrapSize = pProtocol->m_dwSPHeaderSize;
  1203. WrapSize += WrapBuffer(pProtocol, pCmdInfo, pBuffer);
  1204. pFlags=(pFLAGS)&pBuffer->pData[WrapSize];
  1205. pACK = (pACK1)(&pFlags->flag2);
  1206. if(pCmdInfo->flags & BIG){
  1207. // Big packet
  1208. pFlags->flag1 = ACK|BIG;
  1209. pBigACK->sequence = pCmdInfo->sequence;
  1210. pBigACK->serial = pCmdInfo->serial;
  1211. pBigACK->messageid= pCmdInfo->messageid;
  1212. pBigACK->bytes = pSession->LocalBytesReceived;
  1213. pBigACK->time = pCmdInfo->tReceived;
  1214. pBuffer->len = sizeof(ACK2)+1+WrapSize;
  1215. } else {
  1216. // Small packet
  1217. pFlags->flag1 = ACK;
  1218. pACK->messageid = (UCHAR)pCmdInfo->messageid;
  1219. pACK->sequence = (UCHAR)pCmdInfo->sequence;
  1220. pACK->serial = pCmdInfo->serial;
  1221. pACK->bytes = pSession->LocalBytesReceived;
  1222. pACK->time = pCmdInfo->tReceived;
  1223. pBuffer->len = sizeof(ACK1)+1+WrapSize;
  1224. DPF(9,"Send Extra ACK seq=%x, serial=%x\n",pACK->sequence,pACK->serial);
  1225. }
  1226. pFlags->flag1 |= (pCmdInfo->flags & RLY);
  1227. FillInAndSendBuffer(pProtocol,pSession,pSend,pBuffer,pCmdInfo);
  1228. exit1:
  1229. return;
  1230. exit2:
  1231. ReleaseSendDesc(pSend);
  1232. return;
  1233. }
  1234. // Called with receive lock. Returns without lock.
  1235. UINT DGAccept(PPROTOCOL pProtocol, PSESSION pSession, PRECEIVE pReceive, PCMDINFO pCmdInfo, PBUFFER pBuffer)
  1236. {
  1237. ASSERT(!pReceive->fBusy);
  1238. //if(!pReceive->fBusy){
  1239. // Allows datagram receive to start on any serial.
  1240. if(pCmdInfo->flags & STA){
  1241. pReceive->NR=pCmdInfo->serial;
  1242. }
  1243. if(pReceive->NR == pCmdInfo->serial){
  1244. pReceive->iNR++; //really unnecessary, but interesting.
  1245. pReceive->NR = (pReceive->NR+1) & SEQMSK;
  1246. // Add the buffer to the receive buffer list.
  1247. InsertBefore(&pBuffer->BuffList, &pReceive->RcvBuffList);
  1248. pReceive->MessageSize+=(UINT)((pBuffer->pData+pBuffer->len)-pBuffer->pCmdData);
  1249. if(pCmdInfo->flags & EOM){
  1250. DGDeQueueReceive(pSession, pReceive); //unlock's receive.
  1251. IndicateReceive(pProtocol, pSession, pReceive,1);
  1252. } else {
  1253. Unlock(&pReceive->ReceiveLock);
  1254. }
  1255. return TRUE; // ate the buffer.
  1256. } else {
  1257. // Throw this puppy out.
  1258. ASSERT(!pReceive->fBusy);
  1259. DGDeQueueReceive(pSession, pReceive);
  1260. FreeReceive(pProtocol, pReceive);
  1261. }
  1262. //}
  1263. return FALSE;
  1264. }
  1265. UINT CommandReceive(PPROTOCOL pProtocol, PCMDINFO pCmdInfo, PBUFFER pBuffer)
  1266. {
  1267. #define flags pCmdInfo->flags
  1268. PSESSION pSession;
  1269. UINT rc=0; // by default, buffer not accepted.
  1270. PRECEIVE pReceive;
  1271. pSession=GetSysSessionByIndex(pProtocol, pCmdInfo->wIdFrom);
  1272. if(!pSession) {
  1273. DPF(9,"CommandReceive: Throwing out receive for gone session\n");
  1274. goto drop_exit;
  1275. }
  1276. if(flags & BIG){
  1277. if(flags & RLY) {
  1278. pSession->fReceiveSmall=FALSE;
  1279. } else {
  1280. pSession->fReceiveSmallDG=FALSE;
  1281. }
  1282. }
  1283. // See if this receive is already ongoing - if found, it is locked.
  1284. pReceive=GetReceive(pProtocol, pSession, pCmdInfo, pBuffer);
  1285. if(pCmdInfo->command==0){
  1286. pSession->LocalBytesReceived+=pBuffer->len;
  1287. }
  1288. if(!(flags & RLY)){
  1289. if(flags & (SAK|EOM)) {
  1290. SendACK(pProtocol, pSession, pCmdInfo);
  1291. }
  1292. }
  1293. if(pReceive){
  1294. if(flags & RLY){
  1295. // unlocks receive when done.
  1296. rc=ReliableAccept(pProtocol, pSession, pReceive, pCmdInfo, pBuffer);
  1297. } else {
  1298. rc=DGAccept(pProtocol, pSession, pReceive, pCmdInfo, pBuffer);
  1299. }
  1300. }
  1301. DecSessionRef(pSession);
  1302. drop_exit:
  1303. return rc;
  1304. #undef flags
  1305. }
  1306. BOOL CompleteSend(PSESSION pSession, PSEND pSend, PCMDINFO pCmdInfo)
  1307. {
  1308. UINT bit;
  1309. UINT MsgMask;
  1310. pSend->SendState=Done;
  1311. if(pCmdInfo->flags & BIG){
  1312. MsgMask = 0xFFFF;
  1313. } else {
  1314. MsgMask = 0xFF;
  1315. }
  1316. DPF(9,"CompleteSend, pSession %x pSend %x\n",pSession,pSend);
  1317. //
  1318. // Update Session information for completion of this send.
  1319. //
  1320. bit = ((pCmdInfo->messageid-pSession->FirstMsg) & MsgMask)-1;
  1321. // clear the message mask bit for the completed send.
  1322. if(pSession->OutMsgMask & 1<<bit){
  1323. pSession->OutMsgMask &= ~(1<<bit);
  1324. } else {
  1325. Unlock(&pSession->SessionLock);
  1326. return TRUE;
  1327. }
  1328. // slide the first message count forward for each low
  1329. // bit clear in Message mask.
  1330. while(pSession->LastMsg-pSession->FirstMsg){
  1331. if(!(pSession->OutMsgMask & 1)){
  1332. pSession->FirstMsg=(pSession->FirstMsg+1)&MsgMask;
  1333. pSession->OutMsgMask >>= 1;
  1334. if(pSession->nWaitingForMessageid){
  1335. pSession->pProtocol->m_bRescanQueue=TRUE;
  1336. DPF(9,"Signalling reliable ID Sem, nWaitingForMessageid was %d\n",pSession->nWaitingForMessageid);
  1337. SetEvent(pSession->pProtocol->m_hSendEvent);
  1338. }
  1339. } else {
  1340. break;
  1341. }
  1342. }
  1343. //
  1344. // Return the Send to the pool and complete the waiting client.
  1345. //
  1346. Unlock(&pSession->SessionLock);
  1347. ASSERT(pSend->RefCount);
  1348. // Send completed, do completion
  1349. DoSendCompletion(pSend, DP_OK);
  1350. DecSendRef(pSession->pProtocol, pSend); // for completion.
  1351. return TRUE;
  1352. }
  1353. // called with session lock held
  1354. VOID ProcessDGACK(PSESSION pSession, PCMDINFO pCmdInfo)
  1355. {
  1356. BILINK *pBilink;
  1357. PSENDSTAT pStatWalker,pStat=NULL;
  1358. Lock(&pSession->SessionStatLock);
  1359. pBilink=pSession->DGStatList.next;
  1360. while(pBilink != &pSession->DGStatList){
  1361. pStatWalker=CONTAINING_RECORD(pBilink, SENDSTAT, StatList);
  1362. if((pStatWalker->messageid == pCmdInfo->messageid) && // correct messageid
  1363. (pStatWalker->sequence == pCmdInfo->sequence) // correct sequence
  1364. // don't check serial, since datagrams are always serial 0, never retried.
  1365. )
  1366. {
  1367. pStat=pStatWalker;
  1368. break;
  1369. }
  1370. pBilink=pBilink->next;
  1371. }
  1372. if(pStat){
  1373. UpdateSessionStats(pSession,pStat,pCmdInfo,FALSE);
  1374. // Unlink All Previous SENDSTATS;
  1375. pStat->StatList.next->prev=&pSession->DGStatList;
  1376. pSession->DGStatList.next=pStat->StatList.next;
  1377. // Put the SENDSTATS back in the pool.
  1378. while(pBilink != &pSession->DGStatList){
  1379. pStatWalker=CONTAINING_RECORD(pBilink, SENDSTAT, StatList);
  1380. pBilink=pBilink->prev;
  1381. ReleaseSendStat(pStatWalker);
  1382. }
  1383. }
  1384. Unlock(&pSession->SessionStatLock);
  1385. }
  1386. // update a send's information for an ACK.
  1387. // called with SESSIONion lock held.
  1388. // now always drops the sessionlock
  1389. BOOL ProcessReliableACK(PSESSION pSession, PCMDINFO pCmdInfo)
  1390. {
  1391. PSEND pSend=NULL, pSendWalker;
  1392. BILINK *pBilink;
  1393. UINT nFrame;
  1394. UINT nAdvance;
  1395. Unlock(&pSession->SessionLock);
  1396. Lock(&pSession->pProtocol->m_SendQLock);
  1397. Lock(&pSession->SessionLock);
  1398. pBilink=pSession->SendQ.next;
  1399. while(pBilink != &pSession->SendQ){
  1400. pSendWalker=CONTAINING_RECORD(pBilink, SEND, SendQ);
  1401. if((pSendWalker->messageid == pCmdInfo->messageid) && // correct messageid
  1402. (!(pSendWalker->dwFlags & ASEND_PROTOCOL)) && // not and internal message
  1403. (pSendWalker->dwFlags & DPSEND_GUARANTEED)){ // guaranteed
  1404. pSend=pSendWalker;
  1405. break;
  1406. }
  1407. pBilink=pBilink->next;
  1408. }
  1409. // need a reference to avoid processing a send as
  1410. // it is being recycled for another send.
  1411. if(pSend){
  1412. if(!AddSendRef(pSend,1)){
  1413. pSend=NULL;
  1414. }
  1415. }
  1416. Unlock(&pSession->pProtocol->m_SendQLock);
  1417. // SessionLock still held.
  1418. if(pSend){
  1419. Lock(&pSend->SendLock);
  1420. UpdateSessionSendStats(pSession,pSend,pCmdInfo,FALSE);
  1421. // we need to make sure this send isn't already finished.
  1422. switch(pSend->SendState){
  1423. case Sending:
  1424. case Throttled:
  1425. case WaitingForAck:
  1426. case WaitingForId:
  1427. case ReadyToSend:
  1428. break;
  1429. case Start: // shouldn't be getting an ACK for a send in the start state.
  1430. case TimedOut:
  1431. case Cancelled:
  1432. case UserTimeOut:
  1433. case Done:
  1434. // this send is already done, don't do processing on it.
  1435. DPF(4,"PRACK:Not processing ACK on send in State (B#22359 avoided)%x\n",pSend->SendState);
  1436. Unlock(&pSend->SendLock);
  1437. Unlock(&pSession->SessionLock);
  1438. DecSendRef(pSession->pProtocol,pSend); // balances AddSendRef in this fn
  1439. return TRUE; // SessionLock dropped
  1440. break;
  1441. default:
  1442. break;
  1443. }
  1444. pSend->fUpdate=TRUE;
  1445. nFrame=(pCmdInfo->sequence-pSend->NR)&pSend->SendSEQMSK;
  1446. if(nFrame > (pSend->NS - pSend->NR)){
  1447. // Out of range.
  1448. DPF(9,"ReliableACK:Got out of range ACK, SQMSK=%x NS=%d NR=%d ACK=%d\n",pSend->SendSEQMSK,pSend->NS&pSend->SendSEQMSK, pSend->NR&pSend->SendSEQMSK, (pSend->NR+nFrame)&pSend->SendSEQMSK);
  1449. Unlock(&pSend->SendLock);
  1450. Unlock(&pSession->SessionLock);
  1451. DecSendRef(pSession->pProtocol,pSend);
  1452. return TRUE; // SessionLock dropped
  1453. }
  1454. CancelRetryTimer(pSend);
  1455. DPF(9,"ProcessReliableACK (before): pSend->NR %x pSend->OpenWindow %x, pSend->NACKMask %x\n",pSend->NR, pSend->OpenWindow, pSend->NACKMask);
  1456. pSend->NR=(pSend->NR+nFrame);
  1457. pSend->OpenWindow -= nFrame;
  1458. pSend->NACKMask >>= nFrame;
  1459. ASSERT_NACKMask(pSend);
  1460. AdvanceSend(pSend,pSend->FrameDataLen*nFrame); // can put us past on the last frame, but that's ok.
  1461. DPF(9,"ProcessReliableACK: Send->nFrames %2x NR %2x NS %2x nFrame %2x NACKMask %x\n",pSend->nFrames,pSend->NR, pSend->NS, nFrame, pSend->NACKMask);
  1462. if(pSend->NR==pSend->nFrames){
  1463. // LAST ACK, we're done!
  1464. pSend->SendState=Done;
  1465. Unlock(&pSend->SendLock);
  1466. // SessionLock still held
  1467. CompleteSend(pSession, pSend, pCmdInfo);// drops SessionLock
  1468. DecSendRef(pSession->pProtocol,pSend);
  1469. return TRUE;
  1470. } else {
  1471. // set new "NACK bits" for extra window opening
  1472. if(pSend->NR+pSend->OpenWindow+nFrame > pSend->nFrames){
  1473. nAdvance=pSend->nFrames-(pSend->NR+pSend->OpenWindow);
  1474. DPF(9,"A nAdvance %d\n",nAdvance);
  1475. } else {
  1476. nAdvance=nFrame;
  1477. DPF(9,"B nAdvance %d\n",nAdvance);
  1478. }
  1479. pSend->NACKMask |= ((1<<nAdvance)-1)<<pSend->OpenWindow;
  1480. pSend->OpenWindow += nAdvance;
  1481. DPF(9,"pSend->NACKMask=%x\n",pSend->NACKMask);
  1482. ASSERT_NACKMask(pSend);
  1483. }
  1484. switch(pSend->SendState){
  1485. case Start:
  1486. DPF(1,"ERROR, ACK ON UNSTARTED SEND!\n");
  1487. ASSERT(0);
  1488. break;
  1489. case Done:
  1490. DPF(1,"ERROR, ACK ON DONE SEND!\n");
  1491. ASSERT(0);
  1492. break;
  1493. case WaitingForAck:
  1494. pSend->SendState=ReadyToSend;
  1495. SetEvent(pSession->pProtocol->m_hSendEvent);
  1496. break;
  1497. case ReadyToSend:
  1498. case Sending:
  1499. case Throttled:
  1500. default:
  1501. break;
  1502. }
  1503. Unlock(&pSend->SendLock);
  1504. } else {
  1505. DPF(9,"ProcessReliableACK: dup ACK ignoring\n");
  1506. }
  1507. Unlock(&pSession->SessionLock);
  1508. if(pSend){
  1509. DecSendRef(pSession->pProtocol, pSend);
  1510. }
  1511. return TRUE; // SessionLock dropped
  1512. }
  1513. //called with session lock held, always drops lock.
  1514. BOOL ProcessReliableNACK(PSESSION pSession, PCMDINFO pCmdInfo,PUCHAR pNACKmask, UINT nNACK)
  1515. {
  1516. UINT NACKmask=0;
  1517. UINT NACKshift=0;
  1518. PSEND pSend=NULL, pSendWalker;
  1519. BILINK *pBilink;
  1520. UINT nFrame;
  1521. UINT nAdvance;
  1522. UINT nAdvanceShift;
  1523. DWORD nDropped=0;
  1524. DPF(9,"==>ProcessReliableNACK\n");
  1525. Unlock(&pSession->SessionLock);
  1526. Lock(&pSession->pProtocol->m_SendQLock);
  1527. Lock(&pSession->SessionLock);
  1528. pBilink=pSession->SendQ.next;
  1529. while(pBilink != &pSession->SendQ){
  1530. pSendWalker=CONTAINING_RECORD(pBilink, SEND, SendQ);
  1531. if(pSendWalker->dwFlags & DPSEND_GUARANTEE &&
  1532. pSendWalker->messageid == pCmdInfo->messageid){
  1533. pSend=pSendWalker;
  1534. break;
  1535. }
  1536. pBilink=pBilink->next;
  1537. }
  1538. // need a reference to avoid processing a send as
  1539. // it is being recycled for another send.
  1540. if(pSend){
  1541. if(!AddSendRef(pSend,1)){
  1542. pSend=NULL;
  1543. }
  1544. }
  1545. Unlock(&pSession->pProtocol->m_SendQLock);
  1546. // SessionLock still held.
  1547. if(pSend){
  1548. Lock(&pSend->SendLock);
  1549. UpdateSessionSendStats(pSession,pSend,pCmdInfo,FALSE);
  1550. // we need to make sure this send isn't already finished.
  1551. switch(pSend->SendState){
  1552. case Sending:
  1553. case Throttled:
  1554. case WaitingForAck:
  1555. case WaitingForId:
  1556. case ReadyToSend:
  1557. break;
  1558. case Start: // shouldn't be getting an ACK for a send in the start state.
  1559. case TimedOut:
  1560. case Cancelled:
  1561. case UserTimeOut:
  1562. case Done:
  1563. // this send is already done, don't do processing on it.
  1564. DPF(4,"PRNACK:Not processing NACK on send in State (B#22359 avoided)%x\n",pSend->SendState);
  1565. Unlock(&pSend->SendLock);
  1566. Unlock(&pSession->SessionLock);
  1567. DecSendRef(pSession->pProtocol,pSend); // balances AddSendRef in this fn
  1568. return TRUE; // SessionLock dropped
  1569. break;
  1570. default:
  1571. break;
  1572. }
  1573. DPF(9,"Reliable NACK for Send %x, pCmdInfo %x\n",pSend, pCmdInfo);
  1574. pSend->fUpdate=TRUE;
  1575. // Do regular NR updates (BUGBUG: fold with process reliable ACK)
  1576. nFrame=(pCmdInfo->sequence-pSend->NR) & pSend->SendSEQMSK;
  1577. if(nFrame > (pSend->NS - pSend->NR)){
  1578. // Out of range.
  1579. DPF(9,"ReliableNACK:Got out of range NACK, SQMSK=%x NS=%d NR=%d ACK=%d\n",pSend->SendSEQMSK,pSend->NS&pSend->SendSEQMSK, pSend->NR&pSend->SendSEQMSK, (pSend->NR+nFrame)&pSend->SendSEQMSK);
  1580. Unlock(&pSend->SendLock);
  1581. Unlock(&pSession->SessionLock);
  1582. DecSendRef(pSession->pProtocol,pSend);
  1583. return TRUE;
  1584. }
  1585. CancelRetryTimer(pSend);
  1586. DPF(9,"NACK0: pSend->NACKMask %x, OpenWindow %d\n",pSend->NACKMask, pSend->OpenWindow);
  1587. pSend->NR=(pSend->NR+nFrame);
  1588. pSend->OpenWindow -= nFrame;
  1589. pSend->NACKMask >>= nFrame;
  1590. ASSERT_NACKMask(pSend);
  1591. AdvanceSend(pSend,pSend->FrameDataLen*nFrame);
  1592. DPF(9,"ProcessReliableNACK: Send->nFrames %2x NR %2x NS %2x nFrame %2x NACKMask %x\n",pSend->nFrames,pSend->NR, pSend->NS, nFrame, pSend->NACKMask);
  1593. ASSERT(pSend->NR != pSend->nFrames);
  1594. // set new "NACK bits" for extra window opening
  1595. if(pSend->NR+pSend->OpenWindow+nFrame > pSend->nFrames){
  1596. nAdvance=pSend->nFrames-(pSend->NR+pSend->OpenWindow);
  1597. DPF(9, "NACK: 1 nAdvance %d\n",nAdvance);
  1598. } else {
  1599. nAdvance=nFrame;
  1600. DPF(9, "NACK: 2 nAdvance %d\n",nAdvance);
  1601. }
  1602. pSend->NACKMask |= ((1<<nAdvance)-1)<<pSend->OpenWindow;
  1603. DPF(9, "NACK Mask %x\n",pSend->NACKMask);
  1604. pSend->OpenWindow += nAdvance;
  1605. ASSERT_NACKMask(pSend);
  1606. while(nNACK--){
  1607. NACKmask |= (*(pNACKmask++))<<NACKshift;
  1608. NACKshift+=8;
  1609. }
  1610. DPF(9,"NACKmask in NACK %x\n",NACKmask);
  1611. // set the NACK mask.
  1612. nAdvanceShift=0;
  1613. while(NACKmask){
  1614. if(NACKmask&1){
  1615. // set bits are ACKs.
  1616. pSend->NACKMask&=~(1<<nAdvanceShift);
  1617. } else {
  1618. // clear bits are NACKs.
  1619. pSend->NACKMask|=1<<nAdvanceShift;
  1620. nDropped++;
  1621. }
  1622. NACKmask >>= 1;
  1623. nAdvanceShift++;
  1624. }
  1625. DPF(9,"ProcessReliableNACK: pSend->NACKMask=%x\n",pSend->NACKMask);
  1626. ASSERT_NACKMask(pSend);
  1627. UpdateSessionSendStats(pSession,pSend,pCmdInfo, ((nDropped > 1) ? TRUE:FALSE) );
  1628. switch(pSend->SendState){
  1629. case Start:
  1630. DPF(5,"ERROR, NACK ON UNSTARTED SEND!\n");
  1631. ASSERT(0);
  1632. break;
  1633. case Done:
  1634. DPF(5,"ERROR, NACK ON DONE SEND!\n");
  1635. ASSERT(0);
  1636. break;
  1637. case WaitingForAck:
  1638. pSend->SendState=ReadyToSend;
  1639. SetEvent(pSession->pProtocol->m_hSendEvent);
  1640. break;
  1641. case ReadyToSend:
  1642. case Sending:
  1643. case Throttled:
  1644. default:
  1645. break;
  1646. }
  1647. Unlock(&pSend->SendLock);
  1648. } else {
  1649. // BUGBUG: reliable NACK for send we aren't doing? Ignore or send abort?
  1650. DPF(0,"Reliable NACK for send we aren't doing? Ignore?\n");
  1651. }
  1652. Unlock(&pSession->SessionLock);
  1653. if(pSend){
  1654. DecSendRef(pSession->pProtocol,pSend);
  1655. }
  1656. return TRUE;
  1657. #undef pBigNACK
  1658. }
  1659. VOID ProcessACK(PPROTOCOL pProtocol, PCMDINFO pCmdInfo)
  1660. {
  1661. PSESSION pSession;
  1662. UINT rc=0; // by default, buffer not accepted.
  1663. BOOL fUnlockedSession=FALSE;
  1664. // Find the Send for this ACK.
  1665. DPF(9,"ProcessACK\n");
  1666. pSession=GetSysSessionByIndex(pProtocol,pCmdInfo->wIdFrom);
  1667. if(!pSession) {
  1668. goto exit;
  1669. }
  1670. Lock(&pSession->SessionLock);
  1671. // Find the message with the id, make sure its the same type of send.
  1672. if(pCmdInfo->flags & RLY){
  1673. if(pCmdInfo->flags & BIG){
  1674. //BUGBUG: if messageid, FirstMsg and LastMsg are SHORT, no masking req'd
  1675. if((pCmdInfo->messageid==pSession->FirstMsg)||((pCmdInfo->messageid-pSession->FirstMsg)&0xFFFF) > ((pSession->LastMsg-pSession->FirstMsg)&0xFFFF)){
  1676. DPF(9,"Ignoring out of range ACK\n");
  1677. goto exit1;
  1678. }
  1679. } else {
  1680. if((pCmdInfo->messageid==pSession->FirstMsg)||((pCmdInfo->messageid-pSession->FirstMsg)&0xFF) > ((pSession->LastMsg-pSession->FirstMsg)&0xFF)){
  1681. // out of range, ignore
  1682. DPF(9,"Ignoring out of range ACK\n");
  1683. goto exit1;
  1684. }
  1685. }
  1686. ProcessReliableACK(pSession,pCmdInfo); //now always unlocks session.
  1687. fUnlockedSession=TRUE;
  1688. } else {
  1689. ProcessDGACK(pSession,pCmdInfo);
  1690. }
  1691. exit1:
  1692. if(!fUnlockedSession){
  1693. Unlock(&pSession->SessionLock);
  1694. }
  1695. DecSessionRef(pSession);
  1696. exit:
  1697. return;
  1698. #undef pBigACK
  1699. }
  1700. VOID ProcessNACK(PPROTOCOL pProtocol, PCMDINFO pCmdInfo, PUCHAR pNACKmask, UINT nNACK)
  1701. {
  1702. #define pBigNACK ((pNACK2)pNACK)
  1703. PSESSION pSession;
  1704. pSession=GetSysSessionByIndex(pProtocol, pCmdInfo->wIdFrom);
  1705. if(!pSession) {
  1706. ASSERT(0);
  1707. goto exit;
  1708. }
  1709. Lock(&pSession->SessionLock);
  1710. if(pCmdInfo->flags & RLY){
  1711. ProcessReliableNACK(pSession,pCmdInfo,pNACKmask, nNACK); // drops SessionLock
  1712. } else {
  1713. Unlock(&pSession->SessionLock);
  1714. DPF(0,"FATAL: non-reliable NACK???\n");
  1715. ASSERT(0);
  1716. }
  1717. DecSessionRef(pSession);
  1718. exit:
  1719. return;
  1720. }
  1721. UINT AssertMe(REQUEST_PARAMS)
  1722. {
  1723. DEBUG_BREAK();
  1724. return TRUE;
  1725. }
  1726. UINT Ping(REQUEST_PARAMS){return TRUE;}
  1727. UINT PingResp(REQUEST_PARAMS){return TRUE;}
  1728. UINT GetTime(REQUEST_PARAMS){return TRUE;}
  1729. UINT GetTimeResp(REQUEST_PARAMS){return TRUE;}
  1730. UINT SetTime(REQUEST_PARAMS){return TRUE;}
  1731. UINT SetTimeResp(REQUEST_PARAMS){return TRUE;}
  1732. VOID ProcessAbort(PPROTOCOL pProtocol, DPID idFrom, DPID idTo, pABT1 pABT, BOOL fBig){}