COMBUF.CPP 50 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164
  1. /*
  2. ** Command & Conquer Red Alert(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /* $Header: /CounterStrike/COMBUF.CPP 1 3/03/97 10:24a Joe_bostic $ */
  19. /***************************************************************************
  20. ** 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 **
  21. ***************************************************************************
  22. * *
  23. * Project Name : Command & Conquer *
  24. * *
  25. * File Name : COMBUF.CPP *
  26. * *
  27. * Programmer : Bill Randolph *
  28. * *
  29. * Start Date : December 19, 1994 *
  30. * *
  31. * Last Update : October 23, 1995 [BRR] *
  32. * *
  33. *-------------------------------------------------------------------------*
  34. * Functions: *
  35. * CommBufferClass::CommBufferClass -- class constructor *
  36. * CommBufferClass::~CommBufferClass -- class destructor *
  37. * CommBufferClass::Init -- initializes this queue *
  38. * CommBufferClass::Init_Send_Queue -- Clears the send queue *
  39. * CommBufferClass::Queue_Send -- queues a message for sending *
  40. * CommBufferClass::UnQueue_Send -- removes next entry from send queue *
  41. * CommBufferClass::Get_Send -- gets ptr to queue entry *
  42. * CommBufferClass::Queue_Receive -- queues a received message *
  43. * CommBufferClass::UnQueue_Receive -- removes next entry from send queue*
  44. * CommBufferClass::Get_Receive -- gets ptr to queue entry *
  45. * CommBufferClass::Add_Delay -- adds a new delay value for response time*
  46. * CommBufferClass::Avg_Response_Time -- returns average response time *
  47. * CommBufferClass::Max_Response_Time -- returns max response time *
  48. * CommBufferClass::Reset_Response_Time -- resets computations *
  49. * Mono_Debug_Print -- Debug output routine *
  50. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  51. #include "function.h"
  52. #include <stdio.h>
  53. #include <mem.h>
  54. #include "combuf.h"
  55. #include "connect.h" // for command names for debug output
  56. #include "wwlib32.h" // to enable mono output
  57. /***************************************************************************
  58. * CommBufferClass::CommBufferClass -- class constructor *
  59. * *
  60. * INPUT: *
  61. * numsend # queue entries for sending *
  62. * numreceive # queue entries for receiving *
  63. * maxlen maximum desired packet length, in bytes *
  64. * extralen max size of app-specific extra bytes (optional) *
  65. * *
  66. * OUTPUT: *
  67. * none. *
  68. * *
  69. * WARNINGS: *
  70. * none. *
  71. * *
  72. * HISTORY: *
  73. * 12/19/1994 BR : Created. *
  74. *=========================================================================*/
  75. CommBufferClass::CommBufferClass(int numsend, int numreceive, int maxlen,
  76. int extralen)
  77. {
  78. int i;
  79. //------------------------------------------------------------------------
  80. // Init variables
  81. //------------------------------------------------------------------------
  82. MaxSend = numsend;
  83. MaxReceive = numreceive;
  84. MaxPacketSize = maxlen;
  85. MaxExtraSize = extralen;
  86. //------------------------------------------------------------------------
  87. // Allocate the queue entries
  88. //------------------------------------------------------------------------
  89. SendQueue = new SendQueueType[numsend];
  90. ReceiveQueue = new ReceiveQueueType[numreceive];
  91. SendIndex = new int[numsend];
  92. ReceiveIndex = new int[numreceive];
  93. //------------------------------------------------------------------------
  94. // Allocate queue entry buffers
  95. //------------------------------------------------------------------------
  96. for (i = 0; i < MaxSend; i++) {
  97. SendQueue[i].Buffer = new char[maxlen];
  98. if (MaxExtraSize > 0) {
  99. SendQueue[i].ExtraBuffer = new char[MaxExtraSize];
  100. }
  101. else {
  102. SendQueue[i].ExtraBuffer = NULL;
  103. }
  104. }
  105. for (i = 0; i < MaxReceive; i++) {
  106. ReceiveQueue[i].Buffer = new char[maxlen];
  107. if (MaxExtraSize > 0) {
  108. ReceiveQueue[i].ExtraBuffer = new char[MaxExtraSize];
  109. }
  110. else {
  111. ReceiveQueue[i].ExtraBuffer = NULL;
  112. }
  113. }
  114. Init();
  115. } /* end of CommBufferClass */
  116. /***************************************************************************
  117. * CommBufferClass::~CommBufferClass -- class destructor *
  118. * *
  119. * INPUT: *
  120. * none. *
  121. * *
  122. * OUTPUT: *
  123. * none. *
  124. * *
  125. * WARNINGS: *
  126. * none. *
  127. * *
  128. * HISTORY: *
  129. * 12/19/1994 BR : Created. *
  130. *=========================================================================*/
  131. CommBufferClass::~CommBufferClass()
  132. {
  133. int i;
  134. //------------------------------------------------------------------------
  135. // Free queue entry buffers
  136. //------------------------------------------------------------------------
  137. for (i = 0; i < MaxSend; i++) {
  138. delete [] SendQueue[i].Buffer;
  139. if (SendQueue[i].ExtraBuffer) {
  140. delete [] SendQueue[i].ExtraBuffer;
  141. }
  142. }
  143. for (i = 0; i < MaxReceive; i++) {
  144. delete [] ReceiveQueue[i].Buffer;
  145. if (ReceiveQueue[i].ExtraBuffer) {
  146. delete [] ReceiveQueue[i].ExtraBuffer;
  147. }
  148. }
  149. delete [] SendQueue;
  150. delete [] ReceiveQueue;
  151. delete [] SendIndex;
  152. delete [] ReceiveIndex;
  153. } /* end of ~CommBufferClass */
  154. /***************************************************************************
  155. * CommBufferClass::Init -- initializes this queue *
  156. * *
  157. * INPUT: *
  158. * none. *
  159. * *
  160. * OUTPUT: *
  161. * none. *
  162. * *
  163. * WARNINGS: *
  164. * none. *
  165. * *
  166. * HISTORY: *
  167. * 01/20/1995 BR : Created. *
  168. *=========================================================================*/
  169. void CommBufferClass::Init(void)
  170. {
  171. int i;
  172. //------------------------------------------------------------------------
  173. // Init data members
  174. //------------------------------------------------------------------------
  175. SendTotal = 0L;
  176. ReceiveTotal = 0L;
  177. DelaySum = 0L;
  178. NumDelay = 0L;
  179. MeanDelay = 0L;
  180. MaxDelay = 0L;
  181. SendCount = 0;
  182. ReceiveCount = 0;
  183. //------------------------------------------------------------------------
  184. // Init the queue entries
  185. //------------------------------------------------------------------------
  186. for (i = 0; i < MaxSend; i++) {
  187. SendQueue[i].IsActive = 0;
  188. SendQueue[i].IsACK = 0;
  189. SendQueue[i].FirstTime = 0L;
  190. SendQueue[i].LastTime = 0L;
  191. SendQueue[i].SendCount = 0L;
  192. SendQueue[i].BufLen = 0;
  193. SendQueue[i].ExtraLen = 0;
  194. SendIndex[i] = 0;
  195. }
  196. for (i = 0; i < MaxReceive; i++) {
  197. ReceiveQueue[i].IsActive = 0;
  198. ReceiveQueue[i].IsRead = 0;
  199. ReceiveQueue[i].IsACK = 0;
  200. ReceiveQueue[i].BufLen = 0;
  201. ReceiveQueue[i].ExtraLen = 0;
  202. ReceiveIndex[i] = 0;
  203. }
  204. //------------------------------------------------------------------------
  205. // Init debug values
  206. //------------------------------------------------------------------------
  207. DebugOffset = 0;
  208. DebugSize = 0;
  209. DebugNames = NULL;
  210. DebugNameCount = 0;
  211. } /* end of Init */
  212. /***************************************************************************
  213. * CommBufferClass::Init_Send_Queue -- Clears the send queue *
  214. * *
  215. * INPUT: *
  216. * none. *
  217. * *
  218. * OUTPUT: *
  219. * none. *
  220. * *
  221. * WARNINGS: *
  222. * none. *
  223. * *
  224. * HISTORY: *
  225. * 10/23/1995 BRR : Created. *
  226. *=========================================================================*/
  227. void CommBufferClass::Init_Send_Queue(void)
  228. {
  229. int i;
  230. //------------------------------------------------------------------------
  231. // Init data members
  232. //------------------------------------------------------------------------
  233. SendCount = 0;
  234. //------------------------------------------------------------------------
  235. // Init the queue entries
  236. //------------------------------------------------------------------------
  237. for (i = 0; i < MaxSend; i++) {
  238. SendQueue[i].IsActive = 0;
  239. SendQueue[i].IsACK = 0;
  240. SendQueue[i].FirstTime = 0L;
  241. SendQueue[i].LastTime = 0L;
  242. SendQueue[i].SendCount = 0L;
  243. SendQueue[i].BufLen = 0;
  244. SendQueue[i].ExtraLen = 0;
  245. SendIndex[i] = 0;
  246. }
  247. } /* end of Init_Send_Queue */
  248. /***************************************************************************
  249. * CommBufferClass::Queue_Send -- queues a message for sending *
  250. * *
  251. * INPUT: *
  252. * buf buffer containing the message *
  253. * buflen length of 'buf' *
  254. * extrabuf buffer containing extra data (optional) *
  255. * extralen length of extra data (optional) *
  256. * *
  257. * OUTPUT: *
  258. * 1 = OK, 0 = no room in the queue *
  259. * *
  260. * WARNINGS: *
  261. * none. *
  262. * *
  263. * HISTORY: *
  264. * 12/20/1994 BR : Created. *
  265. *=========================================================================*/
  266. int CommBufferClass::Queue_Send(void *buf, int buflen, void *extrabuf,
  267. int extralen)
  268. {
  269. int i;
  270. int index;
  271. //------------------------------------------------------------------------
  272. // Error if no room in the queue
  273. //------------------------------------------------------------------------
  274. if (SendCount==MaxSend || buflen > MaxPacketSize)
  275. return(0);
  276. //------------------------------------------------------------------------
  277. // Find an empty slot
  278. //------------------------------------------------------------------------
  279. index = -1;
  280. for (i = 0; i < MaxSend; i++) {
  281. if (SendQueue[i].IsActive==0) {
  282. index = i;
  283. break;
  284. }
  285. }
  286. if (index == -1)
  287. return (0);
  288. //------------------------------------------------------------------------
  289. // Set entry flags
  290. //------------------------------------------------------------------------
  291. SendQueue[index].IsActive = 1; // entry is now active
  292. SendQueue[index].IsACK = 0; // entry hasn't been ACK'd
  293. SendQueue[index].FirstTime = 0L; // filled in by Manager when sent
  294. SendQueue[index].LastTime = 0L; // filled in by Manager when sent
  295. SendQueue[index].SendCount = 0L; // filled in by Manager when sent
  296. SendQueue[index].BufLen = buflen; // save buffer size
  297. //------------------------------------------------------------------------
  298. // Copy the packet data
  299. //------------------------------------------------------------------------
  300. memcpy(SendQueue[index].Buffer,buf,buflen);
  301. //------------------------------------------------------------------------
  302. // Fill in the extra data, if there is any
  303. //------------------------------------------------------------------------
  304. if (extrabuf!=NULL && extralen > 0 && extralen <= MaxExtraSize) {
  305. memcpy(SendQueue[index].ExtraBuffer,extrabuf,extralen);
  306. SendQueue[index].ExtraLen = extralen;
  307. }
  308. else {
  309. SendQueue[index].ExtraLen = 0;
  310. }
  311. //------------------------------------------------------------------------
  312. // Save this entry's index
  313. //------------------------------------------------------------------------
  314. SendIndex[SendCount] = index;
  315. //------------------------------------------------------------------------
  316. // Increment counters & entry ptr
  317. //------------------------------------------------------------------------
  318. SendCount++;
  319. SendTotal++;
  320. return(1);
  321. } /* end of Queue_Send */
  322. /***************************************************************************
  323. * CommBufferClass::UnQueue_Send -- removes next entry from send queue *
  324. * *
  325. * Frees the given entry; the index given by the caller is the "active" *
  326. * index value (ie the "nth" active entry), not the actual index in the *
  327. * array. *
  328. * *
  329. * INPUT: *
  330. * buf buffer to store entry's data in; if NULL, it's discarded *
  331. * buflen filled in with length of entry retrieved *
  332. * index "index" of entry to un-queue *
  333. * extrabuf buffer for extra data (optional) *
  334. * extralen ptr to length of extra data (optional) *
  335. * *
  336. * OUTPUT: *
  337. * 1 = OK, 0 = no entry to retrieve *
  338. * *
  339. * WARNINGS: *
  340. * none. *
  341. * *
  342. * HISTORY: *
  343. * 12/20/1994 BR : Created. *
  344. *=========================================================================*/
  345. int CommBufferClass::UnQueue_Send(void *buf, int *buflen, int index,
  346. void *extrabuf, int *extralen)
  347. {
  348. int i;
  349. //------------------------------------------------------------------------
  350. // Error if no entry to retrieve
  351. //------------------------------------------------------------------------
  352. if (SendCount==0 || SendQueue[SendIndex[index]].IsActive==0) {
  353. return(0);
  354. }
  355. //------------------------------------------------------------------------
  356. // Copy the data from the entry
  357. //------------------------------------------------------------------------
  358. if (buf!=NULL) {
  359. memcpy(buf,SendQueue[SendIndex[index]].Buffer,
  360. SendQueue[SendIndex[index]].BufLen);
  361. (*buflen) = SendQueue[SendIndex[index]].BufLen;
  362. }
  363. //------------------------------------------------------------------------
  364. // Copy the extra data
  365. //------------------------------------------------------------------------
  366. if (extrabuf!=NULL && extralen!=NULL) {
  367. memcpy(extrabuf,SendQueue[SendIndex[index]].ExtraBuffer,
  368. SendQueue[SendIndex[index]].ExtraLen);
  369. (*extralen) = SendQueue[SendIndex[index]].ExtraLen;
  370. }
  371. //------------------------------------------------------------------------
  372. // Set entry flags
  373. //------------------------------------------------------------------------
  374. SendQueue[SendIndex[index]].IsActive = 0;
  375. SendQueue[SendIndex[index]].IsACK = 0;
  376. SendQueue[SendIndex[index]].FirstTime = 0L;
  377. SendQueue[SendIndex[index]].LastTime = 0L;
  378. SendQueue[SendIndex[index]].SendCount = 0L;
  379. SendQueue[SendIndex[index]].BufLen = 0;
  380. SendQueue[SendIndex[index]].ExtraLen = 0;
  381. //------------------------------------------------------------------------
  382. // Move Indices back one
  383. //------------------------------------------------------------------------
  384. for (i = index; i < SendCount - 1; i++) {
  385. SendIndex[i] = SendIndex[i + 1];
  386. }
  387. SendIndex[SendCount - 1] = 0;
  388. SendCount--;
  389. return(1);
  390. } /* end of UnQueue_Send */
  391. /***************************************************************************
  392. * CommBufferClass::Get_Send -- gets ptr to queue entry *
  393. * *
  394. * This routine gets a pointer to the indicated queue entry. The index *
  395. * value is relative to the next-accessible queue entry; 0 = get the *
  396. * next available queue entry, 1 = get the one behind that, etc. *
  397. * *
  398. * INPUT: *
  399. * index index of entry to get (0 = 1st available) *
  400. * *
  401. * OUTPUT: *
  402. * ptr to entry *
  403. * *
  404. * WARNINGS: *
  405. * none. *
  406. * *
  407. * HISTORY: *
  408. * 12/21/1994 BR : Created. *
  409. *=========================================================================*/
  410. SendQueueType * CommBufferClass::Get_Send(int index)
  411. {
  412. if (SendQueue[SendIndex[index]].IsActive==0) {
  413. return(NULL);
  414. }
  415. else {
  416. return(&SendQueue[SendIndex[index]]);
  417. }
  418. } /* end of Get_Send */
  419. /***************************************************************************
  420. * CommBufferClass::Queue_Receive -- queues a received message *
  421. * *
  422. * INPUT: *
  423. * buf buffer containing the message *
  424. * buflen length of 'buf' *
  425. * extrabuf buffer containing extra data (optional) *
  426. * extralen length of extra data (optional) *
  427. * *
  428. * OUTPUT: *
  429. * 1 = OK, 0 = no room in the queue *
  430. * *
  431. * WARNINGS: *
  432. * none. *
  433. * *
  434. * HISTORY: *
  435. * 12/20/1994 BR : Created. *
  436. *=========================================================================*/
  437. int CommBufferClass::Queue_Receive(void *buf, int buflen, void *extrabuf,
  438. int extralen)
  439. {
  440. int i;
  441. int index;
  442. //------------------------------------------------------------------------
  443. // Error if no room in the queue
  444. //------------------------------------------------------------------------
  445. if (ReceiveCount==MaxReceive || buflen > MaxPacketSize) {
  446. return(0);
  447. }
  448. //------------------------------------------------------------------------
  449. // Find an empty slot
  450. //------------------------------------------------------------------------
  451. index = -1;
  452. for (i = 0; i < MaxReceive; i++) {
  453. if (ReceiveQueue[i].IsActive==0) {
  454. index = i;
  455. break;
  456. }
  457. }
  458. if (index == -1)
  459. return (0);
  460. //------------------------------------------------------------------------
  461. // Set entry flags
  462. //------------------------------------------------------------------------
  463. ReceiveQueue[index].IsActive = 1;
  464. ReceiveQueue[index].IsRead = 0;
  465. ReceiveQueue[index].IsACK = 0;
  466. ReceiveQueue[index].BufLen = buflen;
  467. //------------------------------------------------------------------------
  468. // Copy the packet data
  469. //------------------------------------------------------------------------
  470. memcpy(ReceiveQueue[index].Buffer,buf,buflen);
  471. //------------------------------------------------------------------------
  472. // Fill in the extra data, if there is any
  473. //------------------------------------------------------------------------
  474. if (extrabuf!=NULL && extralen > 0 && extralen <= MaxExtraSize) {
  475. memcpy(ReceiveQueue[index].ExtraBuffer,extrabuf,extralen);
  476. ReceiveQueue[index].ExtraLen = extralen;
  477. }
  478. else {
  479. ReceiveQueue[index].ExtraLen = 0;
  480. }
  481. //------------------------------------------------------------------------
  482. // Save this entry's index
  483. //------------------------------------------------------------------------
  484. ReceiveIndex[ReceiveCount] = index;
  485. //------------------------------------------------------------------------
  486. // Increment counters & entry ptr
  487. //------------------------------------------------------------------------
  488. ReceiveCount++;
  489. ReceiveTotal++;
  490. return(1);
  491. } /* end of Queue_Receive */
  492. /***************************************************************************
  493. * CommBufferClass::UnQueue_Receive -- removes next entry from send queue *
  494. * *
  495. * Frees the given entry; the index given by the caller is the "active" *
  496. * index value (ie the "nth" active entry), not the actual index in the *
  497. * array. *
  498. * *
  499. * INPUT: *
  500. * buf buffer to store entry's data in; if NULL, it's discarded *
  501. * buflen filled in with length of entry retrieved *
  502. * index index of entry to un-queue *
  503. * extrabuf buffer for extra data (optional) *
  504. * extralen ptr to length of extra data (optional) *
  505. * *
  506. * OUTPUT: *
  507. * 1 = OK, 0 = no entry to retrieve *
  508. * *
  509. * WARNINGS: *
  510. * none. *
  511. * *
  512. * HISTORY: *
  513. * 12/20/1994 BR : Created. *
  514. *=========================================================================*/
  515. int CommBufferClass::UnQueue_Receive(void *buf, int *buflen, int index,
  516. void *extrabuf, int *extralen)
  517. {
  518. int i;
  519. //------------------------------------------------------------------------
  520. // Error if no entry to retrieve
  521. //------------------------------------------------------------------------
  522. if (ReceiveCount==0 || ReceiveQueue[ReceiveIndex[index]].IsActive==0) {
  523. return(0);
  524. }
  525. //------------------------------------------------------------------------
  526. // Copy the data from the entry
  527. //------------------------------------------------------------------------
  528. if (buf!=NULL) {
  529. memcpy(buf,ReceiveQueue[ReceiveIndex[index]].Buffer,
  530. ReceiveQueue[ReceiveIndex[index]].BufLen);
  531. (*buflen) = ReceiveQueue[ReceiveIndex[index]].BufLen;
  532. }
  533. //------------------------------------------------------------------------
  534. // Copy the extra data
  535. //------------------------------------------------------------------------
  536. if (extrabuf!=NULL && extralen!=NULL) {
  537. memcpy(extrabuf,ReceiveQueue[ReceiveIndex[index]].ExtraBuffer,
  538. ReceiveQueue[ReceiveIndex[index]].ExtraLen);
  539. (*extralen) = ReceiveQueue[ReceiveIndex[index]].ExtraLen;
  540. }
  541. //------------------------------------------------------------------------
  542. // Set entry flags
  543. //------------------------------------------------------------------------
  544. ReceiveQueue[ReceiveIndex[index]].IsActive = 0;
  545. ReceiveQueue[ReceiveIndex[index]].IsRead = 0;
  546. ReceiveQueue[ReceiveIndex[index]].IsACK = 0;
  547. ReceiveQueue[ReceiveIndex[index]].BufLen = 0;
  548. ReceiveQueue[ReceiveIndex[index]].ExtraLen = 0;
  549. //------------------------------------------------------------------------
  550. // Move Indices back one
  551. //------------------------------------------------------------------------
  552. for (i = index; i < ReceiveCount - 1; i++) {
  553. ReceiveIndex[i] = ReceiveIndex[i + 1];
  554. }
  555. ReceiveIndex[ReceiveCount - 1] = 0;
  556. ReceiveCount--;
  557. return(1);
  558. } /* end of UnQueue_Receive */
  559. /***************************************************************************
  560. * CommBufferClass::Get_Receive -- gets ptr to queue entry *
  561. * *
  562. * This routine gets a pointer to the indicated queue entry. The index *
  563. * value is relative to the next-accessible queue entry; 0 = get the *
  564. * next available queue entry, 1 = get the one behind that, etc. *
  565. * *
  566. * INPUT: *
  567. * index index of entry to get (0 = 1st available) *
  568. * *
  569. * OUTPUT: *
  570. * ptr to entry *
  571. * *
  572. * WARNINGS: *
  573. * none. *
  574. * *
  575. * HISTORY: *
  576. * 12/21/1994 BR : Created. *
  577. *=========================================================================*/
  578. ReceiveQueueType * CommBufferClass::Get_Receive(int index)
  579. {
  580. if (ReceiveQueue[ReceiveIndex[index]].IsActive==0) {
  581. return(NULL);
  582. }
  583. else {
  584. return(&ReceiveQueue[ReceiveIndex[index]]);
  585. }
  586. } /* end of Get_Receive */
  587. /***************************************************************************
  588. * CommBufferClass::Add_Delay -- adds a new delay value for response time *
  589. * *
  590. * This routine updates the average response time for this queue. The *
  591. * computation is based on the average of the last 'n' delay values given, *
  592. * It computes a running total of the last n delay values, then divides *
  593. * that by n to compute the average. *
  594. * *
  595. * When the number of values given exceeds the max, the mean is subtracted *
  596. * off the total, then the new value is added in. Thus, any single delay *
  597. * value will have an effect on the total that approaches 0 over time, and *
  598. * the new delay value contributes to 1/n of the mean. *
  599. * *
  600. * INPUT: *
  601. * delay value to add into the response time computation *
  602. * *
  603. * OUTPUT: *
  604. * none. *
  605. * *
  606. * WARNINGS: *
  607. * none. *
  608. * *
  609. * HISTORY: *
  610. * 01/19/1995 BR : Created. *
  611. *=========================================================================*/
  612. void CommBufferClass::Add_Delay(unsigned long delay)
  613. {
  614. int roundoff = 0;
  615. if (NumDelay==256) {
  616. DelaySum -= MeanDelay;
  617. DelaySum += delay;
  618. if ( (DelaySum & 0x00ff) > 127)
  619. roundoff = 1;
  620. MeanDelay = (DelaySum >> 8) + roundoff;
  621. }
  622. else {
  623. NumDelay++;
  624. DelaySum += delay;
  625. MeanDelay = DelaySum / NumDelay;
  626. }
  627. if (delay > MaxDelay) {
  628. MaxDelay = delay;
  629. }
  630. } /* end of Add_Delay */
  631. /***************************************************************************
  632. * CommBufferClass::Avg_Response_Time -- returns average response time *
  633. * *
  634. * INPUT: *
  635. * none. *
  636. * *
  637. * OUTPUT: *
  638. * latest computed average response time *
  639. * *
  640. * WARNINGS: *
  641. * none. *
  642. * *
  643. * HISTORY: *
  644. * 01/19/1995 BR : Created. *
  645. *=========================================================================*/
  646. unsigned long CommBufferClass::Avg_Response_Time(void)
  647. {
  648. return(MeanDelay);
  649. } /* end of Avg_Response_Time */
  650. /***************************************************************************
  651. * CommBufferClass::Max_Response_Time -- returns max response time *
  652. * *
  653. * INPUT: *
  654. * none. *
  655. * *
  656. * OUTPUT: *
  657. * latest computed average response time *
  658. * *
  659. * WARNINGS: *
  660. * none. *
  661. * *
  662. * HISTORY: *
  663. * 01/19/1995 BR : Created. *
  664. *=========================================================================*/
  665. unsigned long CommBufferClass::Max_Response_Time(void)
  666. {
  667. return(MaxDelay);
  668. } /* end of Max_Response_Time */
  669. /***************************************************************************
  670. * CommBufferClass::Reset_Response_Time -- resets computations *
  671. * *
  672. * INPUT: *
  673. * none. *
  674. * *
  675. * OUTPUT: *
  676. * none. *
  677. * *
  678. * WARNINGS: *
  679. * none. *
  680. * *
  681. * HISTORY: *
  682. * 01/19/1995 BR : Created. *
  683. *=========================================================================*/
  684. void CommBufferClass::Reset_Response_Time(void)
  685. {
  686. DelaySum = 0L;
  687. NumDelay = 0L;
  688. MeanDelay = 0L;
  689. MaxDelay = 0L;
  690. } /* end of Reset_Response_Time */
  691. /***************************************************************************
  692. * CommBufferClass::Configure_Debug -- sets up special debug values *
  693. * *
  694. * Mono_Debug_Print2() can look into a packet to pull out a particular *
  695. * ID, and can print both that ID and a string corresponding to *
  696. * that ID. This routine configures these values so it can find *
  697. * and decode the ID. This ID is used in addition to the normal *
  698. * CommHeaderType values. *
  699. * *
  700. * INPUT: *
  701. * type_offset ID's byte offset into packet *
  702. * type_size size of ID, in bytes; 0 if none *
  703. * names ptr to array of names; use ID as an index into this *
  704. * maxnames max # in the names array; 0 if none. *
  705. * *
  706. * OUTPUT: *
  707. * none. *
  708. * *
  709. * WARNINGS: *
  710. * Names shouldn't be longer than 12 characters. *
  711. * *
  712. * HISTORY: *
  713. * 05/31/1995 BRR : Created. *
  714. *=========================================================================*/
  715. void CommBufferClass::Configure_Debug(int type_offset, int type_size,
  716. char **names, int namestart, int namecount)
  717. {
  718. DebugOffset = type_offset;
  719. DebugSize = type_size;
  720. DebugNames = names;
  721. DebugNameStart = namestart;
  722. DebugNameCount = namecount;
  723. } /* end of Configure_Debug */
  724. /***************************************************************************
  725. * Mono_Debug_Print -- Debug output routine *
  726. * *
  727. * This routine leaves 5 lines at the top for the caller's use. *
  728. * *
  729. * INPUT: *
  730. * refresh 1 = clear screen & completely refresh *
  731. * *
  732. * OUTPUT: *
  733. * none. *
  734. * *
  735. * WARNINGS: *
  736. * none. *
  737. * *
  738. * HISTORY: *
  739. * 05/02/1995 BRR : Created. *
  740. *=========================================================================*/
  741. void CommBufferClass::Mono_Debug_Print(int refresh)
  742. {
  743. #ifdef WWLIB32_H
  744. int i; // loop counter
  745. static int send_col[] = {1,14,28}; // coords of send queue columns
  746. static int receive_col[] = {40,54,68}; // coords of recv queue columns
  747. int row,col; // current row,col for printing
  748. int num; // max # items to print
  749. struct CommHdr { // this mirrors the CommHeaderType
  750. unsigned short MagicNumber;
  751. unsigned char Code;
  752. unsigned long PacketID;
  753. } *hdr;
  754. //------------------------------------------------------------------------
  755. // If few enough entries, call the verbose debug version
  756. //------------------------------------------------------------------------
  757. if (MaxSend <= 16) {
  758. Mono_Debug_Print2(refresh);
  759. return;
  760. }
  761. //------------------------------------------------------------------------
  762. // Refresh the screen
  763. //------------------------------------------------------------------------
  764. if (refresh) {
  765. Mono_Clear_Screen ();
  766. Mono_Printf("ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿\n");
  767. Mono_Printf("³ ³\n");
  768. Mono_Printf("³ ³\n");
  769. Mono_Printf("³ ³\n");
  770. Mono_Printf("ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´\n");
  771. Mono_Printf("³ Send Queue ³ Receive Queue ³\n");
  772. Mono_Printf("³ ³ ³\n");
  773. Mono_Printf("³ ID Ct ACK ID Ct ACK ID Ct ACK³ ID Rd ACK ID Rd ACK ID Rd ACK³\n");
  774. Mono_Printf("³ ³ ³\n");
  775. Mono_Printf("³ ³ ³\n");
  776. Mono_Printf("³ ³ ³\n");
  777. Mono_Printf("³ ³ ³\n");
  778. Mono_Printf("³ ³ ³\n");
  779. Mono_Printf("³ ³ ³\n");
  780. Mono_Printf("³ ³ ³\n");
  781. Mono_Printf("³ ³ ³\n");
  782. Mono_Printf("³ ³ ³\n");
  783. Mono_Printf("³ ³ ³\n");
  784. Mono_Printf("³ ³ ³\n");
  785. Mono_Printf("³ ³ ³\n");
  786. Mono_Printf("³ ³ ³\n");
  787. Mono_Printf("³ ³ ³\n");
  788. Mono_Printf("³ ³ ³\n");
  789. Mono_Printf("³ ³ ³\n");
  790. Mono_Printf("ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ");
  791. }
  792. //------------------------------------------------------------------------
  793. // Print Send Queue items
  794. //------------------------------------------------------------------------
  795. if (MaxSend <= 48) {
  796. num = MaxSend;
  797. }
  798. else {
  799. num = 48;
  800. }
  801. col = 0;
  802. row = 0;
  803. for (i = 0; i < MaxSend; i++) {
  804. Mono_Set_Cursor (send_col[col],row + 8);
  805. if (SendQueue[i].IsActive) {
  806. hdr = (CommHdr *)SendQueue[i].Buffer;
  807. hdr->MagicNumber = hdr->MagicNumber;
  808. hdr->Code = hdr->Code;
  809. Mono_Printf ("%4d %2d %d",hdr->PacketID, SendQueue[i].SendCount,
  810. SendQueue[i].IsACK);
  811. }
  812. else {
  813. Mono_Printf ("____ __ _ ");
  814. }
  815. row++;
  816. if (row > 15) {
  817. row = 0;
  818. col++;
  819. }
  820. }
  821. //------------------------------------------------------------------------
  822. // Print Receive Queue items
  823. //------------------------------------------------------------------------
  824. if (MaxReceive <= 48) {
  825. num = MaxSend;
  826. }
  827. else {
  828. num = 48;
  829. }
  830. col = 0;
  831. row = 0;
  832. for (i = 0; i < MaxReceive; i++) {
  833. Mono_Set_Cursor (receive_col[col],row + 8);
  834. if (ReceiveQueue[i].IsActive) {
  835. hdr = (CommHdr *)ReceiveQueue[i].Buffer;
  836. Mono_Printf ("%4d %d %d",hdr->PacketID, ReceiveQueue[i].IsRead,
  837. ReceiveQueue[i].IsACK);
  838. }
  839. else {
  840. Mono_Printf ("____ _ _ ");
  841. }
  842. row++;
  843. if (row > 15) {
  844. row = 0;
  845. col++;
  846. }
  847. }
  848. #else
  849. refresh = refresh;
  850. #endif
  851. } /* end of Mono_Debug_Print */
  852. /***************************************************************************
  853. * CommBufferClass::Mono_Debug_Print2 -- Debug output; alternate format *
  854. * *
  855. * This routine prints more information than the other version; it's *
  856. * called only if the number of queue entries is small enough to support *
  857. * this format. *
  858. * *
  859. * INPUT: *
  860. * refresh 1 = clear screen & completely refresh *
  861. * *
  862. * OUTPUT: *
  863. * none. *
  864. * *
  865. * WARNINGS: *
  866. * none. *
  867. * *
  868. * HISTORY: *
  869. * 05/31/1995 BRR : Created. *
  870. *=========================================================================*/
  871. void CommBufferClass::Mono_Debug_Print2(int refresh)
  872. {
  873. #ifdef WWLIB32_H
  874. int i; // loop counter
  875. char txt[80];
  876. int val;
  877. struct CommHdr { // this mirrors the CommHeaderType
  878. unsigned short MagicNumber;
  879. unsigned char Code;
  880. unsigned long PacketID;
  881. } *hdr;
  882. //------------------------------------------------------------------------
  883. // Refresh the screen
  884. //------------------------------------------------------------------------
  885. if (refresh) {
  886. Mono_Clear_Screen ();
  887. Mono_Printf("ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿\n");
  888. Mono_Printf("³ ³\n");
  889. Mono_Printf("³ ³\n");
  890. Mono_Printf("³ ³\n");
  891. Mono_Printf("ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´\n");
  892. Mono_Printf("³ Send Queue ³ Receive Queue ³\n");
  893. Mono_Printf("³ ³ ³\n");
  894. Mono_Printf("³ ID Ct Type Data Name ACK ³ ID Rd Type Data Name ACK ³\n");
  895. Mono_Printf("³ ³ ³\n");
  896. Mono_Printf("³ ³ ³\n");
  897. Mono_Printf("³ ³ ³\n");
  898. Mono_Printf("³ ³ ³\n");
  899. Mono_Printf("³ ³ ³\n");
  900. Mono_Printf("³ ³ ³\n");
  901. Mono_Printf("³ ³ ³\n");
  902. Mono_Printf("³ ³ ³\n");
  903. Mono_Printf("³ ³ ³\n");
  904. Mono_Printf("³ ³ ³\n");
  905. Mono_Printf("³ ³ ³\n");
  906. Mono_Printf("³ ³ ³\n");
  907. Mono_Printf("³ ³ ³\n");
  908. Mono_Printf("³ ³ ³\n");
  909. Mono_Printf("³ ³ ³\n");
  910. Mono_Printf("³ ³ ³\n");
  911. Mono_Printf("ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ");
  912. }
  913. //------------------------------------------------------------------------
  914. // Print Send Queue items
  915. //------------------------------------------------------------------------
  916. for (i = 0; i < MaxSend; i++) {
  917. Mono_Set_Cursor (1,8 + i);
  918. //.....................................................................
  919. // Print an active entry
  920. //.....................................................................
  921. if (SendQueue[i].IsActive) {
  922. //..................................................................
  923. // Get header info
  924. //..................................................................
  925. hdr = (CommHdr *)SendQueue[i].Buffer;
  926. hdr->MagicNumber = hdr->MagicNumber;
  927. hdr->Code = hdr->Code;
  928. sprintf(txt,"%4d %2d %-5s ",
  929. hdr->PacketID,
  930. SendQueue[i].SendCount,
  931. ConnectionClass::Command_Name(hdr->Code));
  932. //..................................................................
  933. // Decode app's ID & its name
  934. //..................................................................
  935. if (DebugSize && (DebugOffset + DebugSize) <= SendQueue[i].BufLen) {
  936. if (DebugSize==1) {
  937. val = *(SendQueue[i].Buffer + DebugOffset);
  938. }
  939. else if (DebugSize==2) {
  940. val = *((short *)(SendQueue[i].Buffer + DebugOffset));
  941. }
  942. else if (DebugSize==4) {
  943. val = *((int *)(SendQueue[i].Buffer + DebugOffset));
  944. }
  945. sprintf(txt + strlen(txt),"%4d ",val);
  946. if (DebugNameCount > 0 && val >= 0 && val < DebugNameCount) {
  947. sprintf(txt + strlen(txt),"%-12s %x",
  948. DebugNames[val - DebugNameStart], SendQueue[i].IsACK);
  949. }
  950. else {
  951. sprintf(txt + strlen(txt)," %x",
  952. SendQueue[i].IsACK);
  953. }
  954. }
  955. else {
  956. sprintf(txt + strlen(txt)," %x",
  957. SendQueue[i].IsACK);
  958. }
  959. Mono_Printf("%s",txt);
  960. }
  961. else {
  962. //..................................................................
  963. // Entry isn't active; print blanks
  964. //..................................................................
  965. Mono_Printf("____ __ _");
  966. }
  967. }
  968. //------------------------------------------------------------------------
  969. // Print Receive Queue items
  970. //------------------------------------------------------------------------
  971. for (i = 0; i < MaxReceive; i++) {
  972. Mono_Set_Cursor (40,8 + i);
  973. //.....................................................................
  974. // Print an active entry
  975. //.....................................................................
  976. if (ReceiveQueue[i].IsActive) {
  977. //..................................................................
  978. // Get header info
  979. //..................................................................
  980. hdr = (CommHdr *)ReceiveQueue[i].Buffer;
  981. hdr->MagicNumber = hdr->MagicNumber;
  982. hdr->Code = hdr->Code;
  983. sprintf(txt,"%4d %2d %-5s ",
  984. hdr->PacketID,
  985. ReceiveQueue[i].IsRead,
  986. ConnectionClass::Command_Name(hdr->Code));
  987. //..................................................................
  988. // Decode app's ID & its name
  989. //..................................................................
  990. if (DebugSize && (DebugOffset + DebugSize) <= ReceiveQueue[i].BufLen) {
  991. if (DebugSize==1) {
  992. val = *(ReceiveQueue[i].Buffer + DebugOffset);
  993. }
  994. else if (DebugSize==2) {
  995. val = *((short *)(ReceiveQueue[i].Buffer + DebugOffset));
  996. }
  997. else if (DebugSize==4) {
  998. val = *((int *)(ReceiveQueue[i].Buffer + DebugOffset));
  999. }
  1000. sprintf(txt + strlen(txt),"%4d ",val);
  1001. if (DebugNameCount > 0 && val >= 0 && val < DebugNameCount) {
  1002. sprintf(txt + strlen(txt),"%-12s %x",
  1003. DebugNames[val - DebugNameStart], ReceiveQueue[i].IsACK);
  1004. }
  1005. else {
  1006. sprintf(txt + strlen(txt)," %x",
  1007. ReceiveQueue[i].IsACK);
  1008. }
  1009. }
  1010. else {
  1011. sprintf(txt + strlen(txt)," %x",
  1012. ReceiveQueue[i].IsACK);
  1013. }
  1014. Mono_Printf("%s",txt);
  1015. }
  1016. else {
  1017. //..................................................................
  1018. // Entry isn't active; print blanks
  1019. //..................................................................
  1020. Mono_Printf("____ __ _");
  1021. }
  1022. }
  1023. #else
  1024. refresh = refresh;
  1025. #endif
  1026. } /* end of Mono_Debug_Print2 */
  1027. /************************** end of combuf.cpp ******************************/