NOSEQCON.CPP 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688
  1. //
  2. // Copyright 2020 Electronic Arts Inc.
  3. //
  4. // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free
  5. // software: you can redistribute it and/or modify it under the terms of
  6. // the GNU General Public License as published by the Free Software Foundation,
  7. // either version 3 of the License, or (at your option) any later version.
  8. // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed
  9. // in the hope that it will be useful, but with permitted additional restrictions
  10. // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
  11. // distributed with this program. You should have received a copy of the
  12. // GNU General Public License along with permitted additional restrictions
  13. // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
  14. /* $Header: F:\projects\c&c\vcs\code\noseqcon.cpv 1.10 01 Mar 1996 18:08:30 JOE_BOSTIC $ */
  15. /***************************************************************************
  16. ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
  17. ***************************************************************************
  18. * *
  19. * Project Name : Command & Conquer *
  20. * *
  21. * File Name : SEQCONN.CPP *
  22. * *
  23. * Programmer : Bill Randolph *
  24. * *
  25. * Start Date : December 20, 1994 *
  26. * *
  27. * Last Update : April 9, 1995 [BRR] *
  28. * *
  29. *-------------------------------------------------------------------------*
  30. * Functions: *
  31. * NonSequencedConnClass::NonSequencedConnClass -- class constructor *
  32. * NonSequencedConnClass::~NonSequencedConnClass -- class destructor *
  33. * NonSequencedConnClass::Init -- Initializes connection queue to empty *
  34. * NonSequencedConnClass::Send_Packet -- adds a packet to the send queue *
  35. * NonSequencedConnClass::Receive_Packet -- adds packet to receive queue *
  36. * NonSequencedConnClass::Get_Packet -- gets a packet from receive queue *
  37. * NonSequencedConnClass::Service_Send_Queue -- services the send queue *
  38. * NonSequencedConnClass::Service_Receive_Queue -- services recieve queue*
  39. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  40. #include "function.h"
  41. #include "NOSEQCON.H"
  42. /***************************************************************************
  43. * NonSequencedConnClass::NonSequencedConnClass -- class constructor *
  44. * *
  45. * INPUT: *
  46. * numsend desired # of entries for the send queue *
  47. * numreceive desired # of entries for the recieve queue *
  48. * maxlen max length of an application packet *
  49. * magicnum the packet "magic number" for this connection *
  50. * retry_delta the time to wait between sends *
  51. * max_retries the max # of retries allowed for a packet *
  52. * (-1 means retry forever, based on this parameter) *
  53. * timeout the max amount of time before we give up on a packet *
  54. * (-1 means retry forever, based on this parameter) *
  55. * *
  56. * OUTPUT: *
  57. * none. *
  58. * *
  59. * WARNINGS: *
  60. * none. *
  61. * *
  62. * HISTORY: *
  63. * 12/20/1994 BR : Created. *
  64. *=========================================================================*/
  65. NonSequencedConnClass::NonSequencedConnClass (int numsend, int numreceive,
  66. int maxlen, unsigned short magicnum, unsigned long retry_delta,
  67. unsigned long max_retries, unsigned long timeout) :
  68. ConnectionClass (maxlen, magicnum, retry_delta, max_retries, timeout)
  69. {
  70. /*------------------------------------------------------------------------
  71. Allocate the packet Queue. This will store incoming packets (which will
  72. be placed there by the Connection Manager), and outgoing packets (which
  73. are placed there by this class when it "sends" a packet).
  74. ------------------------------------------------------------------------*/
  75. Queue = new CommBufferClass (numsend, numreceive, MaxPacketLen);
  76. }
  77. /***************************************************************************
  78. * NonSequencedConnClass::~NonSequencedConnClass -- class destructor *
  79. * *
  80. * INPUT: *
  81. * none. *
  82. * *
  83. * OUTPUT: *
  84. * none. *
  85. * *
  86. * WARNINGS: *
  87. * none. *
  88. * *
  89. * HISTORY: *
  90. * 12/20/1994 BR : Created. *
  91. *=========================================================================*/
  92. NonSequencedConnClass::~NonSequencedConnClass ()
  93. {
  94. delete Queue;
  95. }
  96. /***************************************************************************
  97. * NonSequencedConnClass::Init -- Initializes connection queue to empty *
  98. * *
  99. * INPUT: *
  100. * none. *
  101. * *
  102. * OUTPUT: *
  103. * none. *
  104. * *
  105. * WARNINGS: *
  106. * none. *
  107. * *
  108. * HISTORY: *
  109. * 12/20/1994 BR : Created. *
  110. *=========================================================================*/
  111. void NonSequencedConnClass::Init (void)
  112. {
  113. NumRecNoAck = 0;
  114. NumRecAck = 0;
  115. NumSendNoAck = 0;
  116. NumSendAck = 0;
  117. LastSeqID = 0xffffffff;
  118. LastReadID = 0xffffffff;
  119. Queue->Init();
  120. }
  121. /***************************************************************************
  122. * NonSequencedConnClass::Send_Packet -- adds a packet to the send queue *
  123. * *
  124. * This routine prefixes the given buffer with a CommHeaderType and *
  125. * queues the resulting packet into the Send Queue. (It's actually the *
  126. * Service() routine that handles the hardware-dependent Send of the data).*
  127. * The packet's MagicNumber, Code, and PacketID are set here. *
  128. * *
  129. * INPUT: *
  130. * buf buffer to send *
  131. * buflen length of buffer *
  132. * ack_req true = ACK is required for this packet; false = isn't *
  133. * *
  134. * OUTPUT: *
  135. * 1 = packet was queue'd OK, 0 = wasn't *
  136. * *
  137. * WARNINGS: *
  138. * none. *
  139. * *
  140. * HISTORY: *
  141. * 12/20/1994 BR : Created. *
  142. *=========================================================================*/
  143. int NonSequencedConnClass::Send_Packet (void * buf, int buflen, int ack_req)
  144. {
  145. /*........................................................................
  146. Set the magic # for the packet
  147. ........................................................................*/
  148. ((CommHeaderType *)PacketBuf)->MagicNumber = MagicNum;
  149. /*........................................................................
  150. Set the packet Code: DATA_ACK if it requires an ACK, NOACK if it doesn't
  151. Set the packet ID to the appropriate counter value.
  152. ........................................................................*/
  153. if (ack_req) {
  154. ((CommHeaderType *)PacketBuf)->Code = PACKET_DATA_ACK;
  155. ((CommHeaderType *)PacketBuf)->PacketID = NumSendAck;
  156. } else {
  157. ((CommHeaderType *)PacketBuf)->Code = PACKET_DATA_NOACK;
  158. ((CommHeaderType *)PacketBuf)->PacketID = NumSendNoAck;
  159. }
  160. /*........................................................................
  161. Now build the packet
  162. ........................................................................*/
  163. memcpy(PacketBuf + sizeof(CommHeaderType), buf, buflen);
  164. /*........................................................................
  165. Add it to the queue.
  166. ........................................................................*/
  167. if (Queue->Queue_Send(PacketBuf,buflen + sizeof(CommHeaderType))) {
  168. if (ack_req) {
  169. // Smart_Printf( "Packet ack Queued ID %d \n", ((CommHeaderType *)PacketBuf)->PacketID );
  170. NumSendAck++;
  171. } else {
  172. // Smart_Printf( "Packet noack Queued ID %d \n", ((CommHeaderType *)PacketBuf)->PacketID );
  173. NumSendNoAck++;
  174. }
  175. return(true);
  176. } else {
  177. // Smart_Printf( "Packet not Queued ID %d \n", ((CommHeaderType *)PacketBuf)->PacketID );
  178. return(false);
  179. }
  180. }
  181. /***************************************************************************
  182. * NonSequencedConnClass::Receive_Packet -- adds packet to the receive queue *
  183. * *
  184. * INPUT: *
  185. * buf buffer to process (already includes CommHeaderType) *
  186. * buflen length of buffer to process *
  187. * *
  188. * OUTPUT: *
  189. * 1 = packet was processed OK, 0 = error *
  190. * *
  191. * WARNINGS: *
  192. * none. *
  193. * *
  194. * HISTORY: *
  195. * 12/20/1994 BR : Created. *
  196. *=========================================================================*/
  197. int NonSequencedConnClass::Receive_Packet (void * buf, int buflen)
  198. {
  199. CommHeaderType *packet; // ptr to packet header
  200. SendQueueType *send_entry; // ptr to send entry header
  201. ReceiveQueueType *rec_entry; // ptr to recv entry header
  202. CommHeaderType *entry_data; // ptr to queue entry data
  203. CommHeaderType ackpacket; // ACK packet to send
  204. int i;
  205. int save_packet = 1; // 0 = this is a resend
  206. int found;
  207. /*
  208. --------------------------- Check the magic # ----------------------------
  209. */
  210. packet = (CommHeaderType *)buf;
  211. if (packet->MagicNumber != MagicNum) {
  212. // Smart_Printf( "Bad Magic Number\n" );
  213. return(false);
  214. }
  215. /*------------------------------------------------------------------------
  216. Handle an incoming ACK
  217. ------------------------------------------------------------------------*/
  218. if (packet->Code == PACKET_ACK) {
  219. for (i = 0; i < Queue->Num_Send(); i++) {
  220. /*
  221. ....................... Get queue entry ptr ........................
  222. */
  223. send_entry = Queue->Get_Send(i);
  224. /*
  225. ............... If ptr is valid, get ptr to its data ...............
  226. */
  227. if (send_entry != NULL) {
  228. entry_data = (CommHeaderType *)send_entry->Buffer;
  229. /*
  230. .............. If ACK is for this entry, mark it ................
  231. */
  232. if (packet->PacketID==entry_data->PacketID &&
  233. entry_data->Code == PACKET_DATA_ACK) {
  234. // Smart_Printf( "Received ACK for %d \n", packet->PacketID );
  235. send_entry->IsACK = 1;
  236. break;
  237. }
  238. }
  239. }
  240. //{
  241. // if (i == Queue->Num_Send() ) {
  242. // Smart_Printf( "Received bad ACK for %d \n", packet->PacketID );
  243. // }
  244. //}
  245. return(true);
  246. }
  247. /*------------------------------------------------------------------------
  248. Handle an incoming PACKET_DATA_NOACK packet
  249. ------------------------------------------------------------------------*/
  250. else if (packet->Code == PACKET_DATA_NOACK) {
  251. /*---------------------------------------------------------------------
  252. If there's only one slot left, don't tie up the queue with this packet
  253. ---------------------------------------------------------------------*/
  254. if (Queue->Max_Receive() - Queue->Num_Receive() <= 1) {
  255. // Smart_Printf( "Only one slot left don't tie up with DATA NOACK packet %d \n", packet->PacketID );
  256. return(false);
  257. }
  258. /*---------------------------------------------------------------------
  259. Error if we can't queue the packet
  260. ---------------------------------------------------------------------*/
  261. if (!Queue->Queue_Receive (buf, buflen)) {
  262. // Smart_Printf( "Can't Queue the packet %d \n", packet->PacketID );
  263. return(false);
  264. }
  265. // Smart_Printf( "Queued DATA NOACK for %d \n", packet->PacketID );
  266. NumRecNoAck++;
  267. return(true);
  268. }
  269. /*------------------------------------------------------------------------
  270. Handle an incoming PACKET_DATA_ACK packet
  271. ------------------------------------------------------------------------*/
  272. else if (packet->Code == PACKET_DATA_ACK) {
  273. // Smart_Printf( "Looking at ID %d, LastSeqID=%d \n", packet->PacketID, LastSeqID );
  274. /*....................................................................
  275. If this is a packet requires an ACK, and it's ID is older than our
  276. "oldest" ID, we know it's a resend; send an ACK, but don't queue it
  277. ....................................................................*/
  278. if (packet->PacketID <= LastSeqID && LastSeqID != 0xffffffff) {
  279. // Smart_Printf( "Older than oldest\n" );
  280. save_packet = 0;
  281. }
  282. /*....................................................................
  283. Otherwise, scan the queue for this entry; if it's found, it's a
  284. resend, so don't save it.
  285. ....................................................................*/
  286. else {
  287. save_packet = 1;
  288. for (i = 0; i < Queue->Num_Receive(); i++) {
  289. rec_entry = Queue->Get_Receive(i);
  290. if (rec_entry) {
  291. entry_data = (CommHeaderType *)rec_entry->Buffer;
  292. /*...........................................................
  293. Packet is found; it's a resend
  294. ...........................................................*/
  295. if (entry_data->Code == PACKET_DATA_ACK &&
  296. entry_data->PacketID == packet->PacketID) {
  297. // Smart_Printf( "It's a resend\n" );
  298. save_packet = 0;
  299. break;
  300. }
  301. }
  302. }
  303. } /* end of scan for resend */
  304. /*---------------------------------------------------------------------
  305. Queue the packet & update our LastSeqID value.
  306. ---------------------------------------------------------------------*/
  307. if (save_packet) {
  308. /*------------------------------------------------------------------
  309. If there's only one slot left, make sure we only put a packet in it if
  310. this packet will let us increment our LastSeqID; otherwise, we'll get
  311. stuck, forever unable to increment LastSeqID.
  312. ------------------------------------------------------------------*/
  313. if (Queue->Max_Receive() - Queue->Num_Receive() <= 1) {
  314. if (packet->PacketID != (LastSeqID + 1) ) {
  315. // Smart_Printf( "One slot left not what we looking for max=%d,num=%d \n",
  316. // Queue->Max_Receive(), Queue->Num_Receive() );
  317. return(0);
  318. }
  319. }
  320. /*------------------------------------------------------------------
  321. If we can't queue the packet, return; don't send an ACK.
  322. ------------------------------------------------------------------*/
  323. if (!Queue->Queue_Receive (buf, buflen)) {
  324. // Smart_Printf( "unable to queue packet\n" );
  325. return(0);
  326. }
  327. NumRecAck++;
  328. /*------------------------------------------------------------------
  329. Update our LastSeqID value if we can. Anything less than LastSeqID
  330. we'll know is a resend.
  331. ------------------------------------------------------------------*/
  332. if (packet->PacketID == (LastSeqID + 1)) {
  333. LastSeqID = packet->PacketID;
  334. /*............................................................
  335. Now that we have a new 'LastSeqID', search our Queue to see if
  336. the next ID is there; if so, keep checking for the next one;
  337. break only when the next one isn't found. This forces
  338. LastSeqID to be the largest possible value.
  339. ............................................................*/
  340. do {
  341. found = 0;
  342. for (i = 0; i < Queue->Num_Receive(); i++) {
  343. rec_entry = Queue->Get_Receive(i);
  344. if (rec_entry) {
  345. entry_data = (CommHeaderType *)rec_entry->Buffer;
  346. /*......................................................
  347. Entry is found
  348. ......................................................*/
  349. if (entry_data->Code == PACKET_DATA_ACK &&
  350. entry_data->PacketID == (LastSeqID + 1)) {
  351. LastSeqID = entry_data->PacketID;
  352. found = 1;
  353. break;
  354. }
  355. }
  356. }
  357. } while (found);
  358. }
  359. } /* end of save packet */
  360. /*---------------------------------------------------------------------
  361. Send an ACK, regardless of whether this was a resend or not.
  362. ---------------------------------------------------------------------*/
  363. ackpacket.MagicNumber = Magic_Num();
  364. ackpacket.Code = PACKET_ACK;
  365. ackpacket.PacketID = packet->PacketID;
  366. // Smart_Printf( "Sending ACK for %d \n", packet->PacketID );
  367. Send ((char *)&ackpacket, sizeof(CommHeaderType));
  368. return(true);
  369. } else {
  370. // Smart_Printf( "invalid packet type %d \n", packet->Code );
  371. }
  372. return(false);
  373. }
  374. /***************************************************************************
  375. * NonSequencedConnClass::Get_Packet -- gets a packet from receive queue *
  376. * *
  377. * INPUT: *
  378. * buf location to store buffer *
  379. * buflen filled in with length of 'buf' *
  380. * *
  381. * OUTPUT: *
  382. * 1 = packet was read, 0 = wasn't *
  383. * *
  384. * WARNINGS: *
  385. * none. *
  386. * *
  387. * HISTORY: *
  388. * 12/20/1994 BR : Created. *
  389. *=========================================================================*/
  390. int NonSequencedConnClass::Get_Packet (void * buf, int *buflen)
  391. {
  392. ReceiveQueueType *rec_entry; // ptr to receive entry header
  393. int packetlen; // size of received packet
  394. CommHeaderType *entry_data;
  395. int i;
  396. /*------------------------------------------------------------------------
  397. Ensure that we read the packets in order. LastReadID is the ID of the
  398. last PACKET_DATA_ACK packet we read.
  399. ------------------------------------------------------------------------*/
  400. for (i = 0; i < Queue->Num_Receive(); i++) {
  401. rec_entry = Queue->Get_Receive(i);
  402. /*.....................................................................
  403. Only read this entry if it hasn't been yet
  404. .....................................................................*/
  405. if (rec_entry && rec_entry->IsRead==0) {
  406. entry_data = (CommHeaderType *)rec_entry->Buffer;
  407. /*..................................................................
  408. If this is a DATA_ACK packet, its ID must be one greater than
  409. the last one we read.
  410. ..................................................................*/
  411. if ( (entry_data->Code == PACKET_DATA_ACK) &&
  412. (entry_data->PacketID == (LastReadID + 1))) {
  413. LastReadID = entry_data->PacketID;
  414. rec_entry->IsRead = 1;
  415. packetlen = rec_entry->BufLen - sizeof(CommHeaderType);
  416. if (packetlen > 0) {
  417. memcpy(buf, rec_entry->Buffer + sizeof(CommHeaderType), packetlen);
  418. }
  419. (*buflen) = packetlen;
  420. return(true);
  421. }
  422. /*..................................................................
  423. If this is a DATA_NOACK packet, who cares what the ID is?
  424. ..................................................................*/
  425. else if (entry_data->Code == PACKET_DATA_NOACK) {
  426. rec_entry->IsRead = 1;
  427. packetlen = rec_entry->BufLen - sizeof(CommHeaderType);
  428. if (packetlen > 0) {
  429. memcpy(buf, rec_entry->Buffer + sizeof(CommHeaderType), packetlen);
  430. }
  431. (*buflen) = packetlen;
  432. return(true);
  433. }
  434. }
  435. }
  436. return(false);
  437. }
  438. /***************************************************************************
  439. * NonSequencedConnClass::Service_Send_Queue -- services the send queue *
  440. * *
  441. * INPUT: *
  442. * none. *
  443. * *
  444. * OUTPUT: *
  445. * 1 = OK, 0 = error *
  446. * *
  447. * WARNINGS: *
  448. * none. *
  449. * *
  450. * HISTORY: *
  451. * 12/20/1994 BR : Created. *
  452. *=========================================================================*/
  453. int NonSequencedConnClass::Service_Send_Queue (void)
  454. {
  455. int i;
  456. int num_entries;
  457. SendQueueType *send_entry; // ptr to send queue entry
  458. CommHeaderType *packet_hdr; // packet header
  459. unsigned long curtime; // current time
  460. int bad_conn = 0;
  461. /*------------------------------------------------------------------------
  462. Remove any ACK'd packets from the queue
  463. ------------------------------------------------------------------------*/
  464. for (i = 0; i < Queue->Num_Send(); i++) {
  465. /*
  466. ------------------------- Get this queue entry ------------------------
  467. */
  468. send_entry = Queue->Get_Send(i);
  469. /*
  470. ---------------- If ACK has been received, unqueue it -----------------
  471. */
  472. if (send_entry->IsACK) {
  473. /*
  474. ................ Update this queue's response time .................
  475. */
  476. packet_hdr = (CommHeaderType *)send_entry->Buffer;
  477. if (packet_hdr->Code == PACKET_DATA_ACK) {
  478. Queue->Add_Delay(Time() - send_entry->FirstTime);
  479. }
  480. /*
  481. ....................... unqueue the packet .........................
  482. */
  483. Queue->UnQueue_Send(NULL,NULL,i);
  484. i--;
  485. }
  486. }
  487. /*------------------------------------------------------------------------
  488. Loop through all entries in the Send queue. [Re]Send any entries that
  489. need it.
  490. ------------------------------------------------------------------------*/
  491. num_entries = Queue->Num_Send();
  492. for (i = 0; i < num_entries; i++) {
  493. send_entry = Queue->Get_Send(i);
  494. if (send_entry->IsACK) {
  495. continue;
  496. }
  497. /*.....................................................................
  498. Only send the message if time has elapsed. (The message's Time
  499. fields are init'd to 0 when a message is queue'd or unqueue'd, so the
  500. first time through, the delta time will appear large.)
  501. .....................................................................*/
  502. curtime = Time();
  503. if (curtime - send_entry->LastTime > RetryDelta) {
  504. /*
  505. ......................... Send the message .........................
  506. */
  507. #if(0)
  508. {
  509. packet_hdr = (CommHeaderType *)send_entry->Buffer;
  510. if (send_entry->SendCount) {
  511. if (packet_hdr->Code == PACKET_DATA_NOACK) {
  512. // Smart_Printf( "Resending DATA NOACK for %d \n", packet_hdr->PacketID );
  513. } else {
  514. if (packet_hdr->Code == PACKET_DATA_ACK) {
  515. // Smart_Printf( "Resending DATA ACK for %d \n", packet_hdr->PacketID );
  516. }
  517. }
  518. } else {
  519. if (packet_hdr->Code == PACKET_DATA_NOACK) {
  520. // Smart_Printf( "Sending DATA NOACK for %d \n", packet_hdr->PacketID );
  521. } else {
  522. if (packet_hdr->Code == PACKET_DATA_ACK) {
  523. // Smart_Printf( "Sending DATA ACK for %d \n", packet_hdr->PacketID );
  524. }
  525. }
  526. }
  527. }
  528. #endif
  529. Send (send_entry->Buffer, send_entry->BufLen);
  530. /*
  531. ....................... Fill in Time fields ........................
  532. */
  533. send_entry->LastTime = curtime;
  534. if (send_entry->SendCount==0) {
  535. send_entry->FirstTime = curtime;
  536. /*...............................................................
  537. If this is the 1st time we're sending this packet, and it doesn't
  538. require an ACK, mark it as ACK'd; then, the next time through,
  539. it will just be removed from the queue.
  540. ...............................................................*/
  541. packet_hdr = (CommHeaderType *)send_entry->Buffer;
  542. if (packet_hdr->Code == PACKET_DATA_NOACK) {
  543. send_entry->IsACK = 1;
  544. }
  545. }
  546. /*
  547. ......................... Update SendCount .........................
  548. */
  549. send_entry->SendCount++;
  550. /*..................................................................
  551. Perform error detection, based on either MaxRetries or Timeout
  552. ..................................................................*/
  553. if (MaxRetries != -1 && send_entry->SendCount > MaxRetries) {
  554. // Smart_Printf( "Max Retries!!! %d !!! \n", MaxRetries );
  555. bad_conn = 1;
  556. }
  557. if (Timeout != -1 &&
  558. (send_entry->LastTime - send_entry->FirstTime) > Timeout) {
  559. // Smart_Printf( "Timed out!!! Time %d, Timeout %d, buflen %d !!! \n",
  560. // (send_entry->LastTime - send_entry->FirstTime), Timeout,
  561. // send_entry->BufLen );
  562. bad_conn = 1;
  563. }
  564. }
  565. }
  566. /*------------------------------------------------------------------------
  567. If the connection is going bad, return an error
  568. ------------------------------------------------------------------------*/
  569. if (bad_conn) {
  570. // Smart_Printf( "Connection going bad!!! \n" );
  571. return(false);
  572. } else {
  573. return(true);
  574. }
  575. }
  576. /***************************************************************************
  577. * NonSequencedConnClass::Service_Receive_Queue -- services recieve queue *
  578. * *
  579. * INPUT: *
  580. * none. *
  581. * *
  582. * OUTPUT: *
  583. * 1 = OK, 0 = error *
  584. * *
  585. * WARNINGS: *
  586. * none. *
  587. * *
  588. * HISTORY: *
  589. * 12/20/1994 BR : Created. *
  590. *=========================================================================*/
  591. int NonSequencedConnClass::Service_Receive_Queue (void)
  592. {
  593. ReceiveQueueType *rec_entry; // ptr to receive entry header
  594. CommHeaderType *packet_hdr; // packet header
  595. int i;
  596. /*------------------------------------------------------------------------
  597. Remove all dead packets.
  598. PACKET_DATA_NOACK: if it's been read, throw it away.
  599. PACKET_DATA_ACK: if it's been read, and its ID is older than LastSeqID,
  600. throw it away.
  601. ------------------------------------------------------------------------*/
  602. for (i = 0; i < Queue->Num_Receive(); i++) {
  603. rec_entry = Queue->Get_Receive(i);
  604. if (rec_entry->IsRead) {
  605. packet_hdr = (CommHeaderType *)(rec_entry->Buffer);
  606. if (packet_hdr->Code == PACKET_DATA_NOACK) {
  607. Queue->UnQueue_Receive(NULL,NULL,i);
  608. i--;
  609. } else {
  610. if (packet_hdr->PacketID < LastSeqID) {
  611. Queue->UnQueue_Receive(NULL,NULL,i);
  612. i--;
  613. }
  614. }
  615. }
  616. }
  617. return(true);
  618. }