NULLMGR.CPP 88 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350
  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\nullmgr.cpv 1.10 16 Oct 1995 16:51:52 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 : NULLMGR.CPP *
  22. * *
  23. * Programmer : Bill Randolph *
  24. * *
  25. * Start Date : April 5, 1995 *
  26. * *
  27. * Last Update : May 1, 1995 [BRR] *
  28. * *
  29. *-------------------------------------------------------------------------*
  30. * Functions: *
  31. * NullModemClass::NullModemClass -- class constructor *
  32. * NullModemClass::~NullModemClass -- class destructor *
  33. * NullModemClass::Init -- initialization *
  34. * NullModemClass::Send_Message -- sends a message *
  35. * NullModemClass::Get_Message -- polls the Queue for a message *
  36. * NullModemClass::Service -- main polling routine *
  37. * NullModemClass::Num_Send -- Returns # of unACK'd send entries *
  38. * NullModemClass::Num_Receive -- Returns # entries in the receive queue *
  39. * NullModemClass::Response_Time -- Returns Queue's avg response time *
  40. * NullModemClass::Reset_Response_Time -- Resets response time computatio*
  41. * NullModemClass::Oldest_Send -- Returns ptr to oldest unACK'd send buf *
  42. * NullModemClass::Detect_Modem -- Detects and initializes the modem *
  43. * NullModemClass::Dial_Modem -- dials a number passed *
  44. * NullModemClass::Answer_Modem -- waits for call and answers *
  45. * NullModemClass::Hangup_Modem -- hangs up the modem *
  46. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  47. #include "function.h"
  48. #include "wincomm.h"
  49. #include "modemreg.h"
  50. //#include "i86.h"
  51. #include "tcpip.h"
  52. //PG_TO_FIX
  53. #if (0)
  54. extern ModemRegistryEntryClass *ModemRegistry;
  55. // the following line was taken from Greenleaf's <ibmkeys.h> <asciidef.h>
  56. // because of other define conflicts
  57. #define ESC 27
  58. #define NOKEY 0xffff
  59. #define INIT_COMMAND_RETRIES 2
  60. // this time is in milliseconds
  61. #define DEFAULT_TIMEOUT 2000
  62. //
  63. // the following is for a fix around a greenleaf bug
  64. // where they do not check for the value of abortkey
  65. // to determine whether or not they call the abort modem function.
  66. //
  67. extern "C" {
  68. extern void (*_AbortModemFunctionPtr)(int);
  69. }
  70. static void (*NullModemClass::OrigAbortModemFunc)(int);
  71. static KeyNumType NullModemClass::Input;
  72. static GadgetClass *NullModemClass::Commands; // button list
  73. /*
  74. ** Ugly hack: this string stores the string received from the modem
  75. */
  76. char ModemRXString[80];
  77. /***************************************************************************
  78. * NullModemClass::NullModemClass -- class constructor *
  79. * *
  80. * INPUT: *
  81. * numsend # desired entries for the send queue *
  82. * numreceive # desired entries for the receive queue *
  83. * maxlen application's max packet length *
  84. * magicnum application-specific magic # (so we don't *
  85. * accidentally end up talking to another one of our own *
  86. * products using the same protocol) *
  87. * *
  88. * OUTPUT: *
  89. * none. *
  90. * *
  91. * WARNINGS: *
  92. * none. *
  93. * *
  94. * HISTORY: *
  95. * 12/20/1994 BR : Created. *
  96. *=========================================================================*/
  97. NullModemClass::NullModemClass (int numsend, int numreceive, int maxlen,
  98. unsigned short magicnum) : ConnManClass()
  99. {
  100. /*------------------------------------------------------------------------
  101. Init Port to NULL; we haven't opened Greenleaf yet.
  102. ------------------------------------------------------------------------*/
  103. PortHandle = NULL;
  104. Connection = NULL;
  105. NumSend = numsend;
  106. NumReceive = numreceive;
  107. MaxLen = maxlen;
  108. MagicNum = magicnum;
  109. RXBuf = 0;
  110. BuildBuf = 0;
  111. EchoSize = 500;
  112. EchoBuf = 0;
  113. OldIRQPri = -1;
  114. ModemVerboseOn = false; // default true
  115. ModemEchoOn = false; // default true
  116. ModemWaitCarrier = 50000; // default 50 * 1000ms = 50 secs
  117. ModemCarrierDetect = 600; // default 6 * 100ms = .6 secs
  118. ModemCarrierLoss = 1400; // default 14 * 100ms = 1.4 secs
  119. ModemHangupDelay = 20000; // default 20 * 1000ms = 20 secs
  120. ModemGuardTime = 1000; // default 50 * 20ms = 1 sec
  121. ModemEscapeCode = '+'; // default ASCII 43
  122. SendOverflows = 0;
  123. ReceiveOverflows = 0;
  124. CRCErrors = 0;
  125. NumConnections = 0;
  126. /*........................................................................
  127. Init timing parameters
  128. ........................................................................*/
  129. RetryDelta = 60; // 60 ticks between retries
  130. MaxRetries = -1; // disregard # retries
  131. Timeout = 1200; // report bad connection after 20 seconds
  132. } /* end of NullModemClass */
  133. /***************************************************************************
  134. * NullModemClass::~NullModemClass -- class destructor *
  135. * *
  136. * INPUT: *
  137. * none. *
  138. * *
  139. * OUTPUT: *
  140. * none. *
  141. * *
  142. * WARNINGS: *
  143. * none. *
  144. * *
  145. * HISTORY: *
  146. * 12/20/1994 BR : Created. *
  147. *=========================================================================*/
  148. NullModemClass::~NullModemClass ()
  149. {
  150. Delete_Connection();
  151. } /* end of ~NullModemClass */
  152. /***************************************************************************
  153. * NullModemClass::Init -- initialization *
  154. * *
  155. * INPUT: *
  156. * port address *
  157. * irq 2-15 *
  158. * baud 300, 1200, 9600, etc *
  159. * parity 'O' (odd), 'E' (even), 'N' (none), 'S' (space), *
  160. * 'M' (mark) *
  161. * wordlength 5, 6, 7, or 8 *
  162. * stopbits 1 or 2 *
  163. * *
  164. * OUTPUT: *
  165. * 1 = OK, 0 = error *
  166. * *
  167. * WARNINGS: *
  168. * none. *
  169. * *
  170. * HISTORY: *
  171. * 12/20/1994 BR : Created. *
  172. *=========================================================================*/
  173. //int NullModemClass::Init (int port, int irq, int baud, char parity, int wordlen, int stopbits)
  174. #pragma off (unreferenced)
  175. int NullModemClass::Init (int port, int ,char *dev_name, int baud, char parity, int wordlen, int stopbits, int flowcontrol)
  176. {
  177. int com;
  178. //int irqnum;
  179. //int address;
  180. //int status;
  181. if (PortHandle) {
  182. CloseHandle(PortHandle);
  183. PortHandle = NULL;
  184. }
  185. if (!Connection){
  186. /*------------------------------------------------------------------------
  187. Init our Connection
  188. ------------------------------------------------------------------------*/
  189. Connection = new NullModemConnClass (NumSend, NumReceive, MaxLen,
  190. MagicNum);
  191. Connection->Set_Retry_Delta (RetryDelta);
  192. Connection->Set_Max_Retries (MaxRetries);
  193. Connection->Set_TimeOut (Timeout);
  194. /*------------------------------------------------------------------------
  195. Allocate our packet parsing buffer; make it the same # of packets as the
  196. # of receive queue entries the application has requested. Use the
  197. "Actual" maximum packet size, given from the connection; this allows for
  198. both headers that get added to the packet.
  199. ------------------------------------------------------------------------*/
  200. RXSize = Connection->Actual_Max_Packet() * NumReceive;
  201. RXBuf = new char [RXSize];
  202. BuildBuf = new char [MaxLen];
  203. EchoBuf = new char [ EchoSize ];
  204. }
  205. RXCount = 0;
  206. EchoCount = 0;
  207. /*------------------------------------------------------------------------
  208. This call allocates all necessary queue buffers
  209. ------------------------------------------------------------------------*/
  210. switch (port) {
  211. case 0x3f8:
  212. com = COM1;
  213. break;
  214. case 0x2f8:
  215. com = COM2;
  216. break;
  217. case 0x3e8:
  218. com = COM3;
  219. break;
  220. case 0x2e8:
  221. com = COM4;
  222. break;
  223. default:
  224. com = COM5;
  225. break;
  226. }
  227. int i;
  228. /*
  229. ** Create a new modem class for our com port
  230. */
  231. if (!SerialPort) {
  232. SerialPort = new WinModemClass;
  233. }
  234. /*
  235. ** Shift up the baud rate to sensible values
  236. */
  237. // if (baud == 14400) baud = 19200;
  238. // if (baud == 28800) baud = 38400;
  239. static char com_ids[9][5]={
  240. "COM1",
  241. "COM2",
  242. "COM3",
  243. "COM4",
  244. "COM5",
  245. "COM6",
  246. "COM7",
  247. "COM8",
  248. "COM9"
  249. };
  250. char *device;
  251. switch ( port ) {
  252. case 0x3f8:
  253. device = com_ids[0];
  254. break;
  255. case 0x2f8:
  256. device = com_ids[1];
  257. break;
  258. case 0x3e8:
  259. device = com_ids[2];
  260. break;
  261. case 0x2e8:
  262. device = com_ids[3];
  263. break;
  264. case 1:
  265. /*
  266. ** 1 is a special value. It means use the device name not the port address.
  267. */
  268. device = dev_name;
  269. /*
  270. ** If we can match a registry entry with the device name then use that, otherwise use
  271. ** the device name directly to open the port with.
  272. */
  273. if (ModemRegistry){
  274. delete ModemRegistry;
  275. ModemRegistry = NULL;
  276. }
  277. for ( i=0 ; i<10 ; i++ ){
  278. ModemRegistry = new ModemRegistryEntryClass (i);
  279. if (ModemRegistry->Get_Modem_Name()){
  280. if (!strcmp (dev_name, ModemRegistry->Get_Modem_Name() )){
  281. device = ModemRegistry->Get_Modem_Device_Name();
  282. break;
  283. }
  284. }
  285. delete ModemRegistry;
  286. ModemRegistry = NULL;
  287. }
  288. break;
  289. default:
  290. device = NULL;
  291. }
  292. /*
  293. ** Open the com port
  294. */
  295. PortHandle = SerialPort->Serial_Port_Open (device, baud, parity, wordlen, stopbits, flowcontrol);
  296. if (PortHandle == INVALID_HANDLE_VALUE) {
  297. Shutdown();
  298. return(false);
  299. }
  300. /*------------------------------------------------------------------------
  301. Init the Connection
  302. ------------------------------------------------------------------------*/
  303. Connection->Init(PortHandle);
  304. NumConnections = 1;
  305. return(true);
  306. }
  307. /***********************************************************************************************
  308. * NMC::Num_Connections -- returns NumConnections member *
  309. * *
  310. * *
  311. * *
  312. * INPUT: Nothing *
  313. * *
  314. * OUTPUT: NumConnections *
  315. * *
  316. * WARNINGS: None *
  317. * *
  318. * HISTORY: *
  319. * 8/2/96 11:44AM ST : Documented / Win32 support *
  320. *=============================================================================================*/
  321. int NullModemClass::Num_Connections( void )
  322. {
  323. return(NumConnections);
  324. }
  325. /***********************************************************************************************
  326. * NMC::Delete_Connection -- removes the connection *
  327. * *
  328. * *
  329. * *
  330. * INPUT: Nothing *
  331. * *
  332. * OUTPUT: true *
  333. * *
  334. * WARNINGS: None *
  335. * *
  336. * HISTORY: *
  337. * 8/2/96 11:44AM ST : Documented / Win32 support *
  338. *=============================================================================================*/
  339. int NullModemClass::Delete_Connection( void )
  340. {
  341. if (Connection) {
  342. delete Connection;
  343. Connection = NULL;
  344. }
  345. if (RXBuf) {
  346. delete [] RXBuf;
  347. RXBuf = NULL;
  348. }
  349. if (BuildBuf) {
  350. delete [] BuildBuf;
  351. BuildBuf = NULL;
  352. }
  353. if (EchoBuf) {
  354. delete [] EchoBuf;
  355. EchoBuf = NULL;
  356. }
  357. NumConnections = 0;
  358. return( true );
  359. } /* end of Delete_Connection */
  360. /***********************************************************************************************
  361. * NMC::Init_Send_Queue -- Initialises the connections send queue *
  362. * *
  363. * *
  364. * *
  365. * INPUT: Nothing *
  366. * *
  367. * OUTPUT: true *
  368. * *
  369. * WARNINGS: None *
  370. * *
  371. * HISTORY: *
  372. * 8/2/96 11:46AM ST : Documented / Win32 support *
  373. *=============================================================================================*/
  374. int NullModemClass::Init_Send_Queue( void )
  375. {
  376. /*---------------------------------------------------------------
  377. Init the send queue
  378. -----------------------------------------------------------------*/
  379. if ( Connection ) {
  380. Connection->Queue->Init_Send_Queue();
  381. }
  382. return(true);
  383. }
  384. //DetectPortType NullModemClass::Detect_Port( SerialSettingsType *settings )
  385. /***********************************************************************************************
  386. * NMC::Detect_Port -- Checks that the specified com port exists *
  387. * *
  388. * *
  389. * *
  390. * INPUT: ptr to SerialSettingsType *
  391. * *
  392. * OUTPUT: true if port is valid *
  393. * *
  394. * HISTORY: *
  395. * 8/2/96 11:47AM ST : Documented / Win32 support *
  396. *=============================================================================================*/
  397. DetectPortType NullModemClass::Detect_Port( SerialSettingsType *settings)
  398. {
  399. static char com_ids[9][5]={
  400. "COM1",
  401. "COM2",
  402. "COM3",
  403. "COM4",
  404. "COM5",
  405. "COM6",
  406. "COM7",
  407. "COM8",
  408. "COM9"
  409. };
  410. int i;
  411. /*
  412. ** Create a new modem class for our com port
  413. */
  414. if (!SerialPort) {
  415. SerialPort = new WinModemClass;
  416. }else{
  417. SerialPort->Serial_Port_Close();
  418. }
  419. /*
  420. ** Shift up the baud rate to sensible values
  421. */
  422. int baud = settings->Baud;
  423. // if (baud == 14400) baud = 19200;
  424. // if (baud == 28800) baud = 38400;
  425. /*
  426. ** Translate the port address into a usable device name
  427. */
  428. char *device;
  429. switch ( settings->Port ) {
  430. case 0x3f8:
  431. device = com_ids[0];
  432. break;
  433. case 0x2f8:
  434. device = com_ids[1];
  435. break;
  436. case 0x3e8:
  437. device = com_ids[2];
  438. break;
  439. case 0x2e8:
  440. device = com_ids[3];
  441. break;
  442. case 1:
  443. /*
  444. ** 1 is a special value. It means use the device name not the port address.
  445. */
  446. device = settings->ModemName;
  447. /*
  448. ** If we can match a registry entry with the device name then use that, otherwise use
  449. ** the device name directly to open the port with.
  450. */
  451. if (ModemRegistry){
  452. delete ModemRegistry;
  453. ModemRegistry = NULL;
  454. }
  455. for ( i=0 ; i<10 ; i++){
  456. ModemRegistry = new ModemRegistryEntryClass (i);
  457. if (ModemRegistry->Get_Modem_Name()){
  458. if (!strcmp (device, ModemRegistry->Get_Modem_Name() )){
  459. /*
  460. ** Got a match. Break out leaving the registry info intact.
  461. */
  462. device = ModemRegistry->Get_Modem_Device_Name();
  463. break;
  464. }
  465. }
  466. delete ModemRegistry;
  467. ModemRegistry = NULL;
  468. }
  469. break;
  470. default:
  471. return (PORT_INVALID);
  472. }
  473. /*
  474. ** Open the com port
  475. */
  476. HANDLE porthandle = SerialPort->Serial_Port_Open (device, baud, 0, 8, 1, settings->HardwareFlowControl);
  477. if (porthandle == INVALID_HANDLE_VALUE){
  478. return (PORT_INVALID);
  479. }
  480. SerialPort->Serial_Port_Close();
  481. return (PORT_VALID);
  482. }
  483. /***********************************************************************************************
  484. * NullModemClass::ShutDown -- Closes serial port and removes the connection *
  485. * *
  486. * *
  487. * *
  488. * INPUT: Nothing *
  489. * *
  490. * OUTPUT: Nothing *
  491. * *
  492. * WARNINGS: None *
  493. * *
  494. * HISTORY: *
  495. * 8/2/96 11:43AM ST : Documented / Win32 support *
  496. *=============================================================================================*/
  497. void NullModemClass::Shutdown ( void )
  498. {
  499. if (PortHandle && SerialPort) {
  500. SerialPort->Serial_Port_Close();
  501. delete SerialPort;
  502. SerialPort = NULL;
  503. PortHandle = NULL;
  504. Delete_Connection();
  505. }
  506. #ifdef FORCE_WINSOCK
  507. if (Winsock.Get_Connected()){
  508. Delete_Connection();
  509. }
  510. #endif
  511. } /* end of Shutdown */
  512. /***************************************************************************
  513. * NullModemClass::Set_Timing -- sets timing for all connections *
  514. * *
  515. * This will set the timing parameters. This allows an application to *
  516. * measure the Response_Time while running, and adjust timing accordingly. *
  517. * *
  518. * INPUT: *
  519. * retrydelta value to set for retry delta *
  520. * maxretries value to set for max # retries *
  521. * timeout value to set for connection timeout *
  522. * *
  523. * OUTPUT: *
  524. * none. *
  525. * *
  526. * WARNINGS: *
  527. * none. *
  528. * *
  529. * HISTORY: *
  530. * 08/07/1995 DRD : Created. *
  531. *=========================================================================*/
  532. void NullModemClass::Set_Timing (unsigned long retrydelta,
  533. unsigned long maxretries, unsigned long timeout)
  534. {
  535. RetryDelta = retrydelta;
  536. MaxRetries = maxretries;
  537. Timeout = timeout;
  538. Connection->Set_Retry_Delta (RetryDelta);
  539. Connection->Set_Max_Retries (MaxRetries);
  540. Connection->Set_TimeOut (Timeout);
  541. } /* end of Set_Timing */
  542. /***************************************************************************
  543. * NullModemClass::Send_Message -- sends a message *
  544. * *
  545. * For clarity's sake, here's what happens to the buffer passed in: *
  546. * - It gets passed to the Connection's Send_Packet() routine *
  547. * - The CommHeaderType header gets tacked onto it *
  548. * - The resulting buffer gets added to the Connection's Send Queue *
  549. * - When Service() determines that it needs to send the data, it *
  550. * copies the entire packet (CommHeaderType and all) into its local *
  551. * SendBuf, adds the packet start ID, length, and CRC, then sends it out.*
  552. * *
  553. * The ack_req argument will almost always be '1' (the default). The only *
  554. * reason to use 0 is if you don't know whether the other system is *
  555. * ready or not, so you have to periodically send out a query packet, *
  556. * and wait for a response. (Using the connection's built-in retry *
  557. * system would just blast out useless data if the other system isn't *
  558. * even there.) *
  559. * *
  560. * INPUT: *
  561. * buf buffer to send *
  562. * buflen length of buffer *
  563. * ack_req 1 = ACK is required; 0 = not *
  564. * *
  565. * OUTPUT: *
  566. * 1 = OK; 0 = error *
  567. * *
  568. * WARNINGS: *
  569. * none. *
  570. * *
  571. * HISTORY: *
  572. * 12/20/1994 BR : Created. *
  573. *=========================================================================*/
  574. int NullModemClass::Send_Message (void *buf, int buflen, int ack_req)
  575. {
  576. int rc;
  577. if (NumConnections == 0) {
  578. return( false );
  579. }
  580. rc = Connection->Send_Packet(buf,buflen,ack_req);
  581. if (!rc)
  582. SendOverflows++;
  583. return(rc);
  584. } /* end of Send_Message */
  585. /***************************************************************************
  586. * NullModemClass::Get_Message -- polls the Queue for a message *
  587. * *
  588. * INPUT: *
  589. * buf buffer to store message in *
  590. * buflen ptr filled in with length of message *
  591. * *
  592. * OUTPUT: *
  593. * 1 = message was received; 0 = wasn't *
  594. * *
  595. * WARNINGS: *
  596. * none. *
  597. * *
  598. * HISTORY: *
  599. * 12/20/1994 BR : Created. *
  600. *=========================================================================*/
  601. int NullModemClass::Get_Message (void *buf, int *buflen)
  602. {
  603. if (NumConnections == 0) {
  604. return( false );
  605. }
  606. return( Connection->Get_Packet( buf, buflen ) );
  607. }
  608. /***************************************************************************
  609. * NullModemClass::Service -- main polling routine *
  610. * *
  611. * INPUT: *
  612. * none. *
  613. * *
  614. * OUTPUT: *
  615. * 1 = OK, 0 = connection has gone bad *
  616. * *
  617. * WARNINGS: *
  618. * none. *
  619. * *
  620. * HISTORY: *
  621. * 12/20/1994 BR : Created. *
  622. *=========================================================================*/
  623. int NullModemClass::Service (void)
  624. {
  625. int pos; // current position in RXBuf
  626. int i; // loop counter
  627. //int status;
  628. unsigned short length;
  629. SerialHeaderType *header; // decoded packet start, length
  630. SerialCRCType *crc; // decoded packet CRC
  631. char moredata = 0;
  632. if (NumConnections == 0) {
  633. return( false );
  634. }
  635. /*------------------------------------------------------------------------
  636. First, copy all the bytes we can from the Greenleaf RX buffer to our
  637. own buffer.
  638. ------------------------------------------------------------------------*/
  639. RXCount += SerialPort->Read_From_Serial_Port((unsigned char*)(RXBuf + RXCount), int(RXSize - RXCount) );
  640. // if (RXCount){
  641. //char port[128];
  642. //sprintf (port, "C&C95 - RXCount = %d bytes.\n", RXCount);
  643. //CCDebugString (port);
  644. // }
  645. BOOL enabled = FALSE;
  646. #if (0)
  647. if (SerialPort->FramingErrors ||
  648. SerialPort->IOErrors ||
  649. SerialPort->InBufferOverflows ||
  650. SerialPort->BufferOverruns ||
  651. SerialPort->InBufferOverflows ||
  652. SerialPort->OutBufferOverflows){
  653. if (!MonoClass::Is_Enabled()) {
  654. MonoClass::Enable();
  655. enabled = TRUE;
  656. }
  657. Special.IsMonoEnabled = TRUE;
  658. Debug_Smart_Print = TRUE;
  659. Mono_Set_Cursor(0,0);
  660. Smart_Printf( " In Queue: %5d \n", SerialPort->InQueue);
  661. Smart_Printf( " Out Queue: %5d \n", SerialPort->OutQueue);
  662. Smart_Printf( " Framing errors: %5d \n", SerialPort->FramingErrors);
  663. Smart_Printf( " IO errors: %5d \n", SerialPort->IOErrors);
  664. Smart_Printf( " Parity Errors: %5d \n", SerialPort->InBufferOverflows);
  665. Smart_Printf( " Buffer overruns: %5d \n", SerialPort->BufferOverruns);
  666. Smart_Printf( " In buffer overflows: %5d \n", SerialPort->InBufferOverflows);
  667. Smart_Printf( "Out buffer overflows: %5d \n", SerialPort->OutBufferOverflows);
  668. MonoClass::Disable();
  669. Debug_Smart_Print = FALSE;
  670. }
  671. #endif //(0)
  672. // minimum packet size
  673. if ( RXCount < (PACKET_SERIAL_OVERHEAD_SIZE + 1) ) {
  674. return( Connection->Service() );
  675. }
  676. /*------------------------------------------------------------------------
  677. Now scan the buffer for the start of a packet.
  678. ------------------------------------------------------------------------*/
  679. pos = -1;
  680. for (i = 0; i <= RXCount - sizeof( short ); i++) {
  681. if ( *((unsigned short *)(RXBuf + i)) == PACKET_SERIAL_START ) {
  682. pos = i;
  683. break;
  684. }
  685. }
  686. /*------------------------------------------------------------------------
  687. No start code was found; throw away all bytes except the last few, and
  688. return.
  689. ------------------------------------------------------------------------*/
  690. if (pos==-1) {
  691. // Smart_Printf( "No magic number found \n" );
  692. /*.....................................................................
  693. move the remaining, un-checked bytes to the start of the buffer
  694. .....................................................................*/
  695. memmove (RXBuf, RXBuf + i, sizeof( short ) - 1);
  696. RXCount = sizeof( short ) - 1;
  697. return( Connection->Service() );
  698. }
  699. /*........................................................................
  700. Check to see if there are enough bytes for the header to be decoded
  701. ........................................................................*/
  702. if ( (RXCount - pos) < sizeof( SerialHeaderType ) ) {
  703. memmove (RXBuf, RXBuf + pos, RXCount - pos);
  704. RXCount -= pos;
  705. return(Connection->Service());
  706. }
  707. /*------------------------------------------------------------------------
  708. A start code was found; check the packet's length & CRC
  709. ------------------------------------------------------------------------*/
  710. header = (SerialHeaderType *)(RXBuf + pos);
  711. /*........................................................................
  712. If we lost a byte in the length, we may end up waiting a very long time
  713. for the buffer to get to the right length; check the verify value to
  714. make sure this didn't happen.
  715. ........................................................................*/
  716. if ( header->MagicNumber2 != PACKET_SERIAL_VERIFY ) {
  717. // Smart_Printf( "Verify failed\n");
  718. // Hex_Dump_Data( (RXBuf + pos), PACKET_SERIAL_OVERHEAD_SIZE );
  719. pos += sizeof ( short ); // throw away the bogus start code
  720. memmove (RXBuf, RXBuf + pos, RXCount - pos);
  721. RXCount -= pos;
  722. return(Connection->Service());
  723. }
  724. length = header->Length;
  725. /*........................................................................
  726. Special case: if the length comes out too long for us to process:
  727. - Assume the packet is bad
  728. - Throw away the bogus packet-start code
  729. - Return; we'll search for another packet-start code next time.
  730. ........................................................................*/
  731. if (length > MaxLen) {
  732. #if (CONN_DEBUG)
  733. printf( "length too lonnng\n" );
  734. #endif
  735. // Smart_Printf( "length too lonnng %d, max %d \n", length, MaxLen );
  736. pos += sizeof ( short ); // throw away the bogus start code
  737. memmove (RXBuf, RXBuf + pos, RXCount - pos);
  738. RXCount -= pos;
  739. return(Connection->Service());
  740. }
  741. /*........................................................................
  742. If the entire packet isn't stored in our buffer, copy the remaining bytes
  743. to the front of the buffer & return.
  744. ........................................................................*/
  745. if ( (pos + length + PACKET_SERIAL_OVERHEAD_SIZE) > RXCount) {
  746. if ( moredata ) {
  747. // Smart_Printf( "waiting for more data %d, pos = %d \n", ((length + PACKET_SERIAL_OVERHEAD_SIZE) - (RXCount - pos)), pos );
  748. }
  749. if (pos) {
  750. memmove (RXBuf, RXBuf + pos, RXCount - pos);
  751. RXCount -= pos;
  752. }
  753. return(Connection->Service());
  754. }
  755. /*........................................................................
  756. Now grab the CRC value in the packet, & compare it to the CRC value
  757. computed from the actual data. If they don't match, throw away the bogus
  758. start-code, move the rest to the front of the buffer, & return.
  759. We'll continue parsing this data when we're called next time.
  760. ........................................................................*/
  761. crc = (SerialCRCType *)(RXBuf + pos + sizeof( SerialHeaderType ) + length);
  762. if (NullModemConnClass::Compute_CRC(RXBuf + pos +
  763. sizeof( SerialHeaderType ), length) != crc->SerialCRC) {
  764. CRCErrors++;
  765. #if (CONN_DEBUG)
  766. printf( "CRC check failed\n" );
  767. #endif
  768. // Smart_Printf( "CRC check failed for packet of length %d \n", length );
  769. // if (length < 100) {
  770. // Hex_Dump_Data( (RXBuf + pos), (PACKET_SERIAL_OVERHEAD_SIZE + length) );
  771. // }
  772. pos += sizeof ( short ); // throw away the bogus start code
  773. memmove (RXBuf, RXBuf + pos, RXCount - pos);
  774. RXCount -= pos;
  775. return(Connection->Service());
  776. }
  777. /*------------------------------------------------------------------------
  778. Give the new packet to the Connection to process.
  779. ------------------------------------------------------------------------*/
  780. if (!Connection->Receive_Packet(RXBuf + pos + sizeof( SerialHeaderType ), length)) {
  781. ReceiveOverflows++;
  782. // Smart_Printf( "Received overflows %d \n", ReceiveOverflows );
  783. }
  784. #if (0)
  785. Hex_Dump_Data( (RXBuf + pos), (PACKET_SERIAL_OVERHEAD_SIZE + length) );
  786. #endif
  787. /*------------------------------------------------------------------------
  788. Move all data past this packet to the front of the buffer.
  789. ------------------------------------------------------------------------*/
  790. pos += (PACKET_SERIAL_OVERHEAD_SIZE + length);
  791. memmove (RXBuf, RXBuf + pos, RXCount - pos);
  792. RXCount -= pos;
  793. /*------------------------------------------------------------------------
  794. Now, service the connection's Queue's; this will handle ACK & Retries.
  795. ------------------------------------------------------------------------*/
  796. return(Connection->Service());
  797. } /* end of Service */
  798. /***************************************************************************
  799. * NullModemClass::Num_Send -- Returns # of unACK'd send entries *
  800. * *
  801. * INPUT: *
  802. * *
  803. * OUTPUT: *
  804. * *
  805. * WARNINGS: *
  806. * *
  807. * HISTORY: *
  808. * 05/01/1995 BRR : Created. *
  809. *=========================================================================*/
  810. int NullModemClass::Num_Send(void)
  811. {
  812. if (Connection)
  813. return( Connection->Queue->Num_Send() );
  814. else
  815. return (0);
  816. } /* end of Num_Send */
  817. /***************************************************************************
  818. * NullModemClass::Num_Receive -- Returns # entries in the receive queue *
  819. * *
  820. * INPUT: *
  821. * *
  822. * OUTPUT: *
  823. * *
  824. * WARNINGS: *
  825. * *
  826. * HISTORY: *
  827. * 05/01/1995 BRR : Created. *
  828. *=========================================================================*/
  829. int NullModemClass::Num_Receive(void)
  830. {
  831. if (Connection)
  832. return( Connection->Queue->Num_Receive() );
  833. else
  834. return (0);
  835. } /* end of Num_Receive */
  836. /***************************************************************************
  837. * NullModemClass::Response_Time -- Returns Queue's avg response time *
  838. * *
  839. * INPUT: *
  840. * *
  841. * OUTPUT: *
  842. * *
  843. * WARNINGS: *
  844. * *
  845. * HISTORY: *
  846. * 05/01/1995 BRR : Created. *
  847. *=========================================================================*/
  848. unsigned long NullModemClass::Response_Time(void)
  849. {
  850. if (Connection)
  851. return( Connection->Queue->Avg_Response_Time() );
  852. else
  853. return (0);
  854. } /* end of Response_Time */
  855. /***************************************************************************
  856. * NullModemClass::Reset_Response_Time -- Resets response time computation *
  857. * *
  858. * INPUT: *
  859. * *
  860. * OUTPUT: *
  861. * *
  862. * WARNINGS: *
  863. * *
  864. * HISTORY: *
  865. * 05/01/1995 BRR : Created. *
  866. *=========================================================================*/
  867. void NullModemClass::Reset_Response_Time(void)
  868. {
  869. if (Connection)
  870. Connection->Queue->Reset_Response_Time();
  871. } /* end of Reset_Response_Time */
  872. /***************************************************************************
  873. * Oldest_Send -- Returns ptr to oldest unACK'd send buffer *
  874. * *
  875. * INPUT: *
  876. * *
  877. * OUTPUT: *
  878. * *
  879. * WARNINGS: *
  880. * *
  881. * HISTORY: *
  882. * 05/01/1995 BRR : Created. *
  883. *=========================================================================*/
  884. void * NullModemClass::Oldest_Send(void)
  885. {
  886. int i;
  887. SendQueueType *send_entry; // ptr to send entry header
  888. CommHeaderType *packet;
  889. void *buf = NULL;
  890. for (i = 0; i < Connection->Queue->Num_Send(); i++) {
  891. send_entry = Connection->Queue->Get_Send(i);
  892. if (send_entry) {
  893. packet = (CommHeaderType *)send_entry->Buffer;
  894. if (packet->Code == ConnectionClass::PACKET_DATA_ACK && send_entry->IsACK == 0) {
  895. buf = send_entry->Buffer;
  896. break;
  897. }
  898. }
  899. }
  900. return(buf);
  901. } /* end of Oldest_Send */
  902. /***************************************************************************
  903. * NullModemClass::Configure_Debug -- sets up special debug values *
  904. * *
  905. * Mono_Debug_Print2() can look into a packet to pull out a particular *
  906. * ID, and can print both that ID and a string corresponding to *
  907. * that ID. This routine configures these values so it can find *
  908. * and decode the ID. This ID is used in addition to the normal *
  909. * CommHeaderType values. *
  910. * *
  911. * INPUT: *
  912. * index connection index to configure (-1 = Global Channel) *
  913. * offset ID's byte offset into packet *
  914. * size size of ID, in bytes; 0 if none *
  915. * names ptr to array of names; use ID as an index into this *
  916. * maxnames max # in the names array; 0 if none. *
  917. * *
  918. * OUTPUT: *
  919. * none. *
  920. * *
  921. * WARNINGS: *
  922. * Names shouldn't be longer than 12 characters. *
  923. * *
  924. * HISTORY: *
  925. * 05/31/1995 BRR : Created. *
  926. *=========================================================================*/
  927. void NullModemClass::Configure_Debug(int , int offset, int size,
  928. char **names, int maxnames)
  929. {
  930. if (Connection)
  931. Connection->Queue->Configure_Debug (offset, size, names, maxnames);
  932. }
  933. /***************************************************************************
  934. * Mono_Debug_Print -- Debug output routine *
  935. * *
  936. * INPUT: *
  937. * refresh 1 = clear screen & completely refresh *
  938. * *
  939. * OUTPUT: *
  940. * none. *
  941. * *
  942. * WARNINGS: *
  943. * none. *
  944. * *
  945. * HISTORY: *
  946. * 05/02/1995 BRR : Created. *
  947. *=========================================================================*/
  948. void NullModemClass::Mono_Debug_Print(int, int refresh)
  949. {
  950. if (!Connection)
  951. return;
  952. Connection->Queue->Mono_Debug_Print (refresh);
  953. if (refresh) {
  954. Mono_Set_Cursor (31,1);
  955. Mono_Printf ("Serial Port Queues");
  956. Mono_Set_Cursor (9,2);
  957. Mono_Printf ("Average Response Time:");
  958. Mono_Set_Cursor (20,3);
  959. Mono_Printf ("CRC Errors:");
  960. Mono_Set_Cursor (43,2);
  961. Mono_Printf ("Send Overflows:");
  962. Mono_Set_Cursor (40,3);
  963. Mono_Printf ("Receive Overflows:");
  964. }
  965. Mono_Set_Cursor (32,2);
  966. Mono_Printf ("%d ", Connection->Queue->Avg_Response_Time());
  967. Mono_Set_Cursor (32,3);
  968. Mono_Printf ("%d ", CRCErrors);
  969. Mono_Set_Cursor (59,2);
  970. Mono_Printf ("%d ", SendOverflows);
  971. Mono_Set_Cursor (59,3);
  972. Mono_Printf ("%d ", ReceiveOverflows);
  973. Mono_Set_Cursor (2,5);
  974. Mono_Printf ("%d ", Num_Send());
  975. Mono_Set_Cursor (41,5);
  976. Mono_Printf ("%d ", Num_Receive());
  977. } /* end of Mono_Debug_Print */
  978. void Timer_Test (int line, char *file)
  979. {
  980. char abuffer [128];
  981. sprintf (abuffer, "Testing timer at line %d in file %s", line, file);
  982. CCDebugString (abuffer);
  983. CountDownTimerClass timer;
  984. timer.Set (1);
  985. while (timer.Time()){
  986. CCDebugString (".");
  987. }
  988. CCDebugString ("OK\n");
  989. }
  990. /***************************************************************************
  991. * NullModemClass::Detect_Modem -- Detects and initializes the modem *
  992. * *
  993. * INPUT: *
  994. * settings ptr to SerialSettings structure *
  995. * *
  996. * OUTPUT: *
  997. * -1 init string invalid *
  998. * 0 no modem found *
  999. * 1 modem found *
  1000. * *
  1001. * WARNINGS: *
  1002. * none. *
  1003. * *
  1004. * HISTORY: *
  1005. * 06/02/1995 DRD : Created. *
  1006. *=========================================================================*/
  1007. int NullModemClass::Detect_Modem( SerialSettingsType *settings, bool reconnect )
  1008. {
  1009. /*........................................................................
  1010. Button Enumerations
  1011. ........................................................................*/
  1012. // enum {
  1013. // BUTTON_CANCEL = 100,
  1014. // };
  1015. int status;
  1016. // int modemstatus;
  1017. int value;
  1018. int error_count = 0;
  1019. int x,y,width,height; // dialog dimensions
  1020. char buffer[80*3];
  1021. int factor = SeenBuff.Get_Width()/320;
  1022. //Timer_Test(__LINE__, __FILE__);
  1023. /*
  1024. ** Determine the dimensions of the text to be used for the dialog box.
  1025. ** These dimensions will control how the dialog box looks.
  1026. */
  1027. strcpy( buffer, Text_String( TXT_INITIALIZING_MODEM ) );
  1028. Fancy_Text_Print(TXT_NONE,0,0,TBLACK,TBLACK,TPF_6PT_GRAD | TPF_NOSHADOW);
  1029. Format_Window_String(buffer, SeenBuff.Get_Height(), width, height);
  1030. width = MAX(width, 50*factor);
  1031. width += 40*factor;
  1032. height += 60*factor;
  1033. x = (SeenBuff.Get_Width() - width) / 2;
  1034. y = (SeenBuff.Get_Height() - height) / 2;
  1035. /*
  1036. ------------------------------- Initialize -------------------------------
  1037. */
  1038. Set_Logic_Page(SeenBuff);
  1039. /*
  1040. ............................ Draw the dialog .............................
  1041. */
  1042. Hide_Mouse();
  1043. if ( !reconnect ) {
  1044. Load_Title_Screen("HTITLE.PCX", &HidPage, Palette);
  1045. Blit_Hid_Page_To_Seen_Buff();
  1046. }
  1047. Dialog_Box(x, y, width, height);
  1048. Draw_Caption(TXT_NONE, x, y, width);
  1049. Fancy_Text_Print(buffer, x + 20*factor, y + 25*factor, CC_GREEN, TBLACK,
  1050. TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW);
  1051. Show_Mouse();
  1052. HMWaitForOK( 0, NULL );
  1053. /*
  1054. ** OK, lets not mess about any more. Just turn on echo, verbose, and result codes
  1055. ** before we even begin. At least this way when we get an error later on we have already
  1056. ** removed all the steps we use to try and recover.
  1057. ** The timeouts need to be quite small in case the modem is turned off.
  1058. */
  1059. /*
  1060. ** Turn on result codes.
  1061. */
  1062. Send_Modem_Command ( "ATQ0", '\r', buffer, 81, DEFAULT_TIMEOUT / 2, 2);
  1063. /*
  1064. ** Make result codes verbose.
  1065. */
  1066. Send_Modem_Command ( "ATV1", '\r', buffer, 81, DEFAULT_TIMEOUT / 2, 2);
  1067. /*
  1068. ** Turn on echo.
  1069. */
  1070. Send_Modem_Command ( "ATE1", '\r', buffer, 81, DEFAULT_TIMEOUT / 2, 2);
  1071. ModemVerboseOn = true;
  1072. ModemEchoOn = true;
  1073. /*
  1074. ** Try sending a plain old AT command to the modem. Now that we have theoretically
  1075. ** turned on verbose result codes we should get an 'OK' back.
  1076. **
  1077. */
  1078. status = Send_Modem_Command( "AT", '\r', buffer, 81, DEFAULT_TIMEOUT, 2 );
  1079. if (status < ASSUCCESS) {
  1080. /*
  1081. ** No 'OK' came back so return failure. We cant print an error message here because
  1082. ** the calling function may want to upshift the baud rate (eg from 14400 to 19200) and
  1083. ** try again.
  1084. */
  1085. return (false);
  1086. }
  1087. /*
  1088. ** Send the user supplied modem init string
  1089. */
  1090. if (settings->InitStringIndex == -1) {
  1091. status = Send_Modem_Command( "", '\r', buffer, 81, 300, 1 );
  1092. } else {
  1093. /*
  1094. ** Split up the init string into seperate strings if it contains one or more '|' characters.
  1095. ** This character acts as a carriage return/pause.
  1096. */
  1097. char *istr = new char [2 + strlen( InitStrings [settings->InitStringIndex] )];
  1098. char *tokenptr;
  1099. strcpy (istr, InitStrings [settings->InitStringIndex] );
  1100. /*
  1101. ** Tokenise the string and send it in chunks
  1102. */
  1103. tokenptr = strtok ( istr, "|" );
  1104. while ( tokenptr ) {
  1105. status = Send_Modem_Command( tokenptr, '\r', buffer, 81, DEFAULT_TIMEOUT, 1 );
  1106. /*
  1107. ** Handle error case.
  1108. */
  1109. if (status < ASSUCCESS) {
  1110. if (CCMessageBox().Process(TXT_ERROR_NO_INIT, TXT_IGNORE, TXT_CANCEL)) {
  1111. delete istr;
  1112. return( false );
  1113. }
  1114. error_count++;
  1115. break;
  1116. }
  1117. tokenptr = strtok ( NULL, "|");
  1118. }
  1119. }
  1120. /*
  1121. ** Use the settings from the registry to further initialise the modem
  1122. */
  1123. if (settings->Port == 1 && ModemRegistry) {
  1124. /*
  1125. ** Send the init strings from the registry if available
  1126. */
  1127. char send_string[256] = {"AT"};
  1128. if (settings->HardwareFlowControl){
  1129. /*
  1130. ** Send the init string for hardware flow control
  1131. */
  1132. if (ModemRegistry->Get_Modem_Hardware_Flow_Control()) {
  1133. strcpy (&send_string[2], ModemRegistry->Get_Modem_Hardware_Flow_Control());
  1134. status = Send_Modem_Command (send_string, '\r', buffer, 81, DEFAULT_TIMEOUT, 1);
  1135. if (status != MODEM_CMD_OK && status != MODEM_CMD_0) {
  1136. if (CCMessageBox().Process(TXT_NO_FLOW_CONTROL_RESPONSE, TXT_IGNORE, TXT_CANCEL)) return (false);
  1137. }
  1138. }
  1139. }else{
  1140. /*
  1141. ** Send the init string for no flow control
  1142. */
  1143. if (ModemRegistry->Get_Modem_No_Flow_Control()) {
  1144. strcpy (&send_string[2], ModemRegistry->Get_Modem_No_Flow_Control());
  1145. status = Send_Modem_Command (send_string, '\r', buffer, 81, DEFAULT_TIMEOUT, 1);
  1146. if (status != MODEM_CMD_OK && status != MODEM_CMD_0) {
  1147. if (CCMessageBox().Process(TXT_NO_FLOW_CONTROL_RESPONSE, TXT_IGNORE, TXT_CANCEL)) return (false);
  1148. }
  1149. }
  1150. }
  1151. /*
  1152. ** Send the string for data compresseion
  1153. */
  1154. if (settings->Compression){
  1155. if (ModemRegistry->Get_Modem_Compression_Enable()) {
  1156. strcpy (&send_string[2], ModemRegistry->Get_Modem_Compression_Enable());
  1157. Send_Modem_Command (send_string, '\r', buffer, 81, DEFAULT_TIMEOUT, 1);
  1158. if (status != MODEM_CMD_OK && status != MODEM_CMD_0) {
  1159. if (CCMessageBox().Process(TXT_NO_COMPRESSION_RESPONSE, TXT_IGNORE, TXT_CANCEL)) return (false);
  1160. }
  1161. }
  1162. }else{
  1163. if (ModemRegistry->Get_Modem_Compression_Disable()) {
  1164. strcpy (&send_string[2], ModemRegistry->Get_Modem_Compression_Disable());
  1165. Send_Modem_Command (send_string, '\r', buffer, 81, DEFAULT_TIMEOUT, 1);
  1166. if (status != MODEM_CMD_OK && status != MODEM_CMD_0) {
  1167. if (CCMessageBox().Process(TXT_NO_COMPRESSION_RESPONSE, TXT_IGNORE, TXT_CANCEL)) return (false);
  1168. }
  1169. }
  1170. }
  1171. /*
  1172. ** Send the string for error correction
  1173. */
  1174. if (settings->ErrorCorrection){
  1175. if (ModemRegistry->Get_Modem_Error_Correction_Enable()) {
  1176. strcpy (&send_string[2], ModemRegistry->Get_Modem_Error_Correction_Enable());
  1177. Send_Modem_Command (send_string, '\r', buffer, 81, DEFAULT_TIMEOUT, 1);
  1178. if (status != MODEM_CMD_OK && status != MODEM_CMD_0) {
  1179. if (CCMessageBox().Process(TXT_NO_ERROR_CORRECTION_RESPONSE, TXT_IGNORE, TXT_CANCEL)) return (false);
  1180. }
  1181. }
  1182. }else{
  1183. if (ModemRegistry->Get_Modem_Error_Correction_Disable()) {
  1184. strcpy (&send_string[2], ModemRegistry->Get_Modem_Error_Correction_Disable());
  1185. Send_Modem_Command (send_string, '\r', buffer, 81, DEFAULT_TIMEOUT, 1);
  1186. if (status != MODEM_CMD_OK && status != MODEM_CMD_0) {
  1187. if (CCMessageBox().Process(TXT_NO_ERROR_CORRECTION_RESPONSE, TXT_IGNORE, TXT_CANCEL)) return (false);
  1188. }
  1189. }
  1190. }
  1191. }
  1192. /*
  1193. ** We require that auto-answer be disabled so turn it off now.
  1194. */
  1195. status = Send_Modem_Command( "ATS0=0", '\r', buffer, 81, DEFAULT_TIMEOUT, INIT_COMMAND_RETRIES );
  1196. if (status != MODEM_CMD_OK) {
  1197. if (CCMessageBox().Process(TXT_ERROR_NO_DISABLE, TXT_IGNORE, TXT_CANCEL)) return( false );
  1198. error_count++;
  1199. }
  1200. /*
  1201. ** If we had an unreasonable number of ignored errors then return failure
  1202. */
  1203. if (error_count >= 3) {
  1204. CCMessageBox().Process(TXT_ERROR_TOO_MANY, TXT_OK);
  1205. return (false);
  1206. }
  1207. return( true );
  1208. }
  1209. /***************************************************************************
  1210. * NullModemClass::Dial_Modem -- dials a number passed *
  1211. * *
  1212. * INPUT: *
  1213. * settings ptr to SerialSettings structure *
  1214. * *
  1215. * OUTPUT: *
  1216. * status DialStatus *
  1217. * *
  1218. * WARNINGS: *
  1219. * none. *
  1220. * *
  1221. * HISTORY: *
  1222. * 06/02/1995 DRD : Created. *
  1223. *=========================================================================*/
  1224. DialStatusType NullModemClass::Dial_Modem( char *string, DialMethodType method, bool reconnect )
  1225. {
  1226. //Timer_Test(__LINE__, __FILE__);
  1227. int factor = SeenBuff.Get_Width()/320;
  1228. /*........................................................................
  1229. Button Enumerations
  1230. ........................................................................*/
  1231. enum {
  1232. BUTTON_CANCEL = 100,
  1233. };
  1234. /*........................................................................
  1235. Dialog variables
  1236. ........................................................................*/
  1237. bool process = true; // process while true
  1238. //int status;
  1239. int delay;
  1240. DialStatusType dialstatus;
  1241. int x,y,width,height; // dialog dimensions
  1242. char buffer[80*3];
  1243. Input = 0;
  1244. //Timer_Test(__LINE__, __FILE__);
  1245. /*
  1246. ** Determine the dimensions of the text to be used for the dialog box.
  1247. ** These dimensions will control how the dialog box looks.
  1248. */
  1249. if (reconnect) {
  1250. strcpy( buffer, Text_String( TXT_MODEM_CONNERR_REDIALING ) );
  1251. } else {
  1252. strcpy( buffer, Text_String( TXT_DIALING ) );
  1253. }
  1254. //Timer_Test(__LINE__, __FILE__);
  1255. Fancy_Text_Print(TXT_NONE,0,0,TBLACK,TBLACK,TPF_6PT_GRAD | TPF_NOSHADOW);
  1256. Format_Window_String(buffer, SeenBuff.Get_Height(), width, height);
  1257. int text_width = width;
  1258. width = MAX(width, 50*factor);
  1259. width += 40*factor;
  1260. height += 60*factor;
  1261. x = (SeenBuff.Get_Width() - width) / 2;
  1262. y = (SeenBuff.Get_Height() - height) / 2;
  1263. TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL,
  1264. TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
  1265. x + ((width - (String_Pixel_Width( Text_String( TXT_CANCEL ) ) + 8*factor)) >> 1),
  1266. y + height - (FontHeight + FontYSpacing + 2*factor) - 5*factor);
  1267. //Timer_Test(__LINE__, __FILE__);
  1268. /*
  1269. ------------------------------- Initialize -------------------------------
  1270. */
  1271. Set_Logic_Page(SeenBuff);
  1272. /*
  1273. ............................ Create the list .............................
  1274. */
  1275. Commands = &cancelbtn;
  1276. //Timer_Test(__LINE__, __FILE__);
  1277. Commands->Flag_List_To_Redraw();
  1278. //Timer_Test(__LINE__, __FILE__);
  1279. /*
  1280. ............................ Draw the dialog .............................
  1281. */
  1282. Hide_Mouse();
  1283. if ( !reconnect ) {
  1284. Load_Title_Screen("HTITLE.PCX", &HidPage, Palette);
  1285. Blit_Hid_Page_To_Seen_Buff();
  1286. }
  1287. //Timer_Test(__LINE__, __FILE__);
  1288. Dialog_Box(x, y, width, height);
  1289. Draw_Caption(TXT_NONE, x, y, width);
  1290. //Timer_Test(__LINE__, __FILE__);
  1291. Fancy_Text_Print(buffer, SeenBuff.Get_Width()/2 - text_width/2, y + 25*factor, CC_GREEN, TBLACK,
  1292. TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW);
  1293. //Timer_Test(__LINE__, __FILE__);
  1294. CCDebugString ("C&C95 - About to draw buttons.\n");
  1295. Commands->Draw_All();
  1296. CCDebugString ("C&C95 - About to show mouse.\n");
  1297. Show_Mouse();
  1298. //Timer_Test(__LINE__, __FILE__);
  1299. // start waiting
  1300. //CCDebugString ("C&C95 - About to delay for 2 seconds.\n");
  1301. //Delay(120);
  1302. //HMSetDialingMethod( Port, (int)method );
  1303. CCDebugString ("C&C95 - About to set modem dial type.\n");
  1304. SerialPort->Set_Modem_Dial_Type((WinCommDialMethodType) method);
  1305. //Timer_Test(__LINE__, __FILE__);
  1306. //Clear out any old modem result codes
  1307. CCDebugString ("C&C95 - About to call 'Get_Modem_Result'.\n");
  1308. SerialPort->Get_Modem_Result(60, buffer, 81);
  1309. //status = HMDial( Port, string );
  1310. CCDebugString ("C&C95 - About to call 'SerialPort->Dial_Modem'.\n");
  1311. SerialPort->Dial_Modem(string);
  1312. //Timer_Test(__LINE__, __FILE__);
  1313. //
  1314. // Sets up the ability to abort modem commands when any input is in the
  1315. // Keyboard buffer. This also calls the game CallBack().
  1316. //
  1317. CCDebugString ("C&C95 - About to call 'Setup_Abort_Modem'.\n");
  1318. Setup_Abort_Modem();
  1319. //Timer_Test(__LINE__, __FILE__);
  1320. /*
  1321. -------------------------- Main Processing Loop --------------------------
  1322. */
  1323. process = true;
  1324. delay = ModemWaitCarrier;
  1325. CCDebugString ("C&C95 - About to enter main process loop.\n");
  1326. while (process) {
  1327. //Timer_Test(__LINE__, __FILE__);
  1328. /*
  1329. ** If we have just received input focus again after running in the background then
  1330. ** we need to redraw.
  1331. */
  1332. if (AllSurfaces.SurfacesRestored){
  1333. CCDebugString ("C&C95 - About to restore video surfaces.\n");
  1334. AllSurfaces.SurfacesRestored=FALSE;
  1335. Commands->Draw_All();
  1336. }
  1337. //Timer_Test(__LINE__, __FILE__);
  1338. //delay = HMInputLine( Port, delay, buffer, 81 );
  1339. CCDebugString ("C&C95 - About to call 'Get_Modem_Result 2'.\n");
  1340. //Timer_Test(__LINE__, __FILE__);
  1341. char abuffer [128];
  1342. sprintf (abuffer, "C&C95 - ModemWaitCarrier delay = %d\n", delay);
  1343. CCDebugString (abuffer);
  1344. delay = SerialPort->Get_Modem_Result(delay, buffer, 81);
  1345. /*
  1346. ............................ Process input ............................
  1347. */
  1348. CCDebugString ("C&C95 - About to check for keyboard input.\n");
  1349. if (!Input) Input = Commands->Input();
  1350. switch (Input) {
  1351. case (KN_ESC):
  1352. case (BUTTON_CANCEL | KN_BUTTON):
  1353. dialstatus = DIAL_CANCELED;
  1354. process = false;
  1355. break;
  1356. default:
  1357. break;
  1358. }
  1359. if (process) {
  1360. if ( strncmp( buffer, "CON", 3 ) == 0 ) {
  1361. memset (ModemRXString, 0, 80);
  1362. strncpy (ModemRXString, buffer, 79);
  1363. dialstatus = DIAL_CONNECTED;
  1364. process = false;
  1365. }
  1366. else if ( strncmp( buffer, "BUSY", 4 ) == 0 ) {
  1367. dialstatus = DIAL_BUSY;
  1368. process = false;
  1369. }
  1370. else if ( strncmp( buffer, "NO C", 4 ) == 0 ) {
  1371. dialstatus = DIAL_NO_CARRIER;
  1372. process = false;
  1373. }
  1374. else if ( strncmp( buffer, "NO D", 4 ) == 0 ) {
  1375. dialstatus = DIAL_NO_DIAL_TONE;
  1376. process = false;
  1377. }
  1378. else if ( strncmp( buffer, "ERRO", 4 ) == 0 ) {
  1379. dialstatus = DIAL_ERROR;
  1380. process = false;
  1381. }
  1382. }
  1383. if (delay <= 0) {
  1384. if (delay < 0) {
  1385. }
  1386. process = false;
  1387. }
  1388. }
  1389. Remove_Abort_Modem();
  1390. return( dialstatus );
  1391. } /* end of Dial_Modem */
  1392. /***************************************************************************
  1393. * NullModemClass::Answer_Modem -- waits for call and answers *
  1394. * *
  1395. * INPUT: *
  1396. * reconnect whether this is to reconnect *
  1397. * *
  1398. * OUTPUT: *
  1399. * status DialStatus *
  1400. * *
  1401. * WARNINGS: *
  1402. * none. *
  1403. * *
  1404. * HISTORY: *
  1405. * 06/02/1995 DRD : Created. *
  1406. *=========================================================================*/
  1407. DialStatusType NullModemClass::Answer_Modem( bool reconnect )
  1408. {
  1409. int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2;
  1410. /*........................................................................
  1411. Button Enumerations
  1412. ........................................................................*/
  1413. enum {
  1414. BUTTON_CANCEL = 100,
  1415. };
  1416. /*........................................................................
  1417. Redraw values: in order from "top" to "bottom" layer of the dialog
  1418. ........................................................................*/
  1419. typedef enum {
  1420. REDRAW_NONE = 0,
  1421. REDRAW_BUTTONS,
  1422. REDRAW_BACKGROUND,
  1423. REDRAW_ALL = REDRAW_BACKGROUND
  1424. } RedrawType;
  1425. /*........................................................................
  1426. Dialog variables
  1427. ........................................................................*/
  1428. RedrawType display = REDRAW_ALL; // redraw level
  1429. bool process = true; // process while true
  1430. //int status;
  1431. int delay;
  1432. DialStatusType dialstatus;
  1433. bool ring = false;
  1434. int x,y,width,height; // dialog dimensions
  1435. char text_buffer[80*3];
  1436. char comm_buffer[80*3];
  1437. int text_width;
  1438. /*
  1439. ** Determine the dimensions of the text to be used for the dialog box.
  1440. ** These dimensions will control how the dialog box looks.
  1441. */
  1442. if (reconnect) {
  1443. strcpy( text_buffer, Text_String( TXT_MODEM_CONNERR_WAITING ) );
  1444. } else {
  1445. strcpy( text_buffer, Text_String( TXT_WAITING_FOR_CALL ) );
  1446. }
  1447. Fancy_Text_Print(TXT_NONE,0,0,TBLACK,TBLACK,TPF_6PT_GRAD | TPF_NOSHADOW);
  1448. Format_Window_String(text_buffer, SeenBuff.Get_Height(), width, height);
  1449. text_width = width;
  1450. width = MAX(width, 50*factor);
  1451. width += 40*factor;
  1452. height += 60*factor;
  1453. x = (SeenBuff.Get_Width() - width) / 2;
  1454. y = (SeenBuff.Get_Height() - height) / 2;
  1455. TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL,
  1456. TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
  1457. x + ((width - (String_Pixel_Width( Text_String( TXT_CANCEL ) ) + 8*factor)) >> 1),
  1458. y + height - (FontHeight + FontYSpacing + 2*factor) - 5*factor);
  1459. /*
  1460. ------------------------------- Initialize -------------------------------
  1461. */
  1462. Set_Logic_Page(SeenBuff);
  1463. //Load_Picture("TITLE.CPS", HidPage, HidPage, Palette, BM_DEFAULT);
  1464. Input = 0;
  1465. /*
  1466. ............................ Create the list .............................
  1467. */
  1468. Commands = &cancelbtn;
  1469. Commands->Flag_List_To_Redraw();
  1470. // start waiting
  1471. // HMWaitForOK( 1000, NULL );
  1472. // status = HMSendString( Port, "ATS0=1" );
  1473. //
  1474. // Sets up the ability to abort modem commands when any input is in the
  1475. // Keyboard buffer. This also calls the game CallBack() and Input().
  1476. //
  1477. Setup_Abort_Modem();
  1478. /*
  1479. -------------------------- Main Processing Loop --------------------------
  1480. */
  1481. process = true;
  1482. delay = 60000;
  1483. while (process) {
  1484. /*
  1485. ** If we have just received input focus again after running in the background then
  1486. ** we need to redraw.
  1487. */
  1488. if (AllSurfaces.SurfacesRestored){
  1489. AllSurfaces.SurfacesRestored=FALSE;
  1490. display=REDRAW_ALL;
  1491. }
  1492. /*
  1493. ...................... Refresh display if needed ......................
  1494. */
  1495. if (display) {
  1496. Hide_Mouse();
  1497. if (display >= REDRAW_BACKGROUND) {
  1498. /*
  1499. ..................... Refresh the backdrop ......................
  1500. */
  1501. if ( !reconnect ) {
  1502. Load_Title_Screen("HTITLE.PCX", &HidPage, Palette);
  1503. Blit_Hid_Page_To_Seen_Buff();
  1504. }
  1505. /*
  1506. ..................... Draw the background .......................
  1507. */
  1508. Dialog_Box(x, y, width, height);
  1509. /*
  1510. ....................... Draw the labels .........................
  1511. */
  1512. Draw_Caption(TXT_NONE, x, y, width);
  1513. Fancy_Text_Print(text_buffer, SeenBuff.Get_Width()/2 - text_width/2, y + 25*factor, CC_GREEN, TBLACK,
  1514. TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW);
  1515. Commands->Draw_All();
  1516. }
  1517. Show_Mouse();
  1518. display = REDRAW_NONE;
  1519. }
  1520. //delay = HMInputLine( Port, delay, buffer, 81 );
  1521. delay = SerialPort->Get_Modem_Result(delay, comm_buffer, 81);
  1522. /*
  1523. ............................ Process input ............................
  1524. */
  1525. if (!Input) Input = Commands->Input();
  1526. switch (Input) {
  1527. case (KN_ESC):
  1528. case (BUTTON_CANCEL | KN_BUTTON):
  1529. // Sound_Effect(VOC_BUTTON,255);
  1530. dialstatus = DIAL_CANCELED;
  1531. process = false;
  1532. break;
  1533. default:
  1534. break;
  1535. }
  1536. if (process) {
  1537. if ( strncmp( comm_buffer, "RING", 4 ) == 0 ) {
  1538. strcpy( text_buffer, Text_String( TXT_ANSWERING ) );
  1539. Fancy_Text_Print(TXT_NONE,0,0,TBLACK,TBLACK,TPF_6PT_GRAD | TPF_NOSHADOW);
  1540. Format_Window_String(text_buffer, SeenBuff.Get_Height(), width, height);
  1541. text_width = width;
  1542. width = MAX(width, 50*factor);
  1543. width += 40*factor;
  1544. height += 60*factor;
  1545. x = (SeenBuff.Get_Width() - width) / 2;
  1546. y = (SeenBuff.Get_Height() - height) / 2;
  1547. //PortKillTime( Port, 100 );
  1548. //HMWaitForOK( 0, NULL );
  1549. //status = HMAnswer( Port );
  1550. SerialPort->Write_To_Serial_Port ((unsigned char*)"ATA\r", strlen("ATA\r"));
  1551. ring = true;
  1552. delay = ModemWaitCarrier;
  1553. display = REDRAW_ALL;
  1554. }
  1555. else if ( strncmp( comm_buffer, "CON", 3 ) == 0 ) {
  1556. memset (ModemRXString, 0, 80);
  1557. strncpy (ModemRXString, comm_buffer, 79);
  1558. dialstatus = DIAL_CONNECTED;
  1559. process = false;
  1560. }
  1561. else if ( strncmp( comm_buffer, "BUSY", 4 ) == 0 ) {
  1562. dialstatus = DIAL_BUSY;
  1563. process = false;
  1564. }
  1565. else if ( strncmp( comm_buffer, "NO C", 4 ) == 0 ) {
  1566. dialstatus = DIAL_NO_CARRIER;
  1567. process = false;
  1568. }
  1569. else if ( strncmp( comm_buffer, "NO D", 4 ) == 0 ) {
  1570. dialstatus = DIAL_NO_DIAL_TONE;
  1571. process = false;
  1572. }
  1573. else if ( strncmp( comm_buffer, "ERRO", 4 ) == 0 ) {
  1574. dialstatus = DIAL_ERROR;
  1575. CCMessageBox().Process ("Error - Modem returned error status.", TXT_OK);
  1576. process = false;
  1577. }
  1578. }
  1579. if (delay <= 0) {
  1580. if (ring) {
  1581. if (SerialPort->Get_Modem_Status() & CD_SET){
  1582. sprintf(ModemRXString, "%s", "Connected");
  1583. dialstatus = DIAL_CONNECTED;
  1584. }else{
  1585. dialstatus = DIAL_ERROR;
  1586. CCMessageBox().Process ("Error - TIme out waiting for connect.", TXT_OK);
  1587. }
  1588. process = false;
  1589. } else {
  1590. delay = 60000;
  1591. }
  1592. }
  1593. }
  1594. Remove_Abort_Modem();
  1595. return( dialstatus );
  1596. } /* end of Answer_Modem */
  1597. /***************************************************************************
  1598. * NullModemClass::Hangup_Modem -- hangs up the modem *
  1599. * *
  1600. * INPUT: *
  1601. * none *
  1602. * *
  1603. * OUTPUT: *
  1604. * status successful or not *
  1605. * *
  1606. * WARNINGS: *
  1607. * none. *
  1608. * *
  1609. * HISTORY: *
  1610. * 06/02/1995 DRD : Created. *
  1611. *=========================================================================*/
  1612. bool NullModemClass::Hangup_Modem( void )
  1613. {
  1614. int status;
  1615. int delay;
  1616. char buffer[81];
  1617. char escape[4];
  1618. /*
  1619. ** Turn modem servicing off in the callback routine.
  1620. */
  1621. ModemService = false;
  1622. status = Send_Modem_Command( "AT", '\r', buffer, 81, DEFAULT_TIMEOUT, 1 );
  1623. if (status == MODEM_CMD_OK) {
  1624. ModemService = true;
  1625. return( true );
  1626. }
  1627. SerialPort->Set_Serial_DTR(FALSE);
  1628. Delay(3200/60);
  1629. SerialPort->Set_Serial_DTR(TRUE);
  1630. //SetDtr( Port, 0 );
  1631. //PortKillTime( Port, 3200 );
  1632. //SetDtr( Port, 1 );
  1633. status = Send_Modem_Command( "AT", '\r', buffer, 81, DEFAULT_TIMEOUT, 1 );
  1634. if (status == MODEM_CMD_OK) {
  1635. ModemService = true;
  1636. return( true );
  1637. }
  1638. delay = ModemGuardTime;
  1639. while ( delay > 0 ) {
  1640. //delay = HMInputLine( Port, delay, buffer, 81 );
  1641. delay = SerialPort->Get_Modem_Result(delay, buffer, 81);
  1642. }
  1643. escape[0] = ModemEscapeCode;
  1644. escape[1] = ModemEscapeCode;
  1645. escape[2] = ModemEscapeCode;
  1646. escape[3] = 0;
  1647. //status = HMSendStringNoWait( Port, escape, -1 );
  1648. SerialPort->Write_To_Serial_Port((unsigned char*)escape, 3);
  1649. delay = ModemGuardTime;
  1650. while ( delay > 0 ) {
  1651. delay = SerialPort->Get_Modem_Result(delay, buffer, 81);
  1652. //delay = HMInputLine( Port, delay, buffer, 81 );
  1653. if ( strncmp( buffer, "OK", 2 ) == 0 ) {
  1654. break;
  1655. }
  1656. }
  1657. status = Send_Modem_Command( "ATH", '\r', buffer, 81, ModemHangupDelay, 1 );
  1658. if (status == MODEM_CMD_OK) {
  1659. } else {
  1660. ModemService = true;
  1661. return( false );
  1662. }
  1663. status = Send_Modem_Command( "ATZ", '\r', buffer, 81, DEFAULT_TIMEOUT, 1 );
  1664. if (status == MODEM_CMD_OK) {
  1665. } else {
  1666. ModemService = true;
  1667. return( false );
  1668. }
  1669. ModemService = true;
  1670. return( true );
  1671. } /* end of Hangup_Modem */
  1672. /***********************************************************************************************
  1673. * NMC::Setup_Modem_Echo -- Sets the echo callback function pointer *
  1674. * *
  1675. * *
  1676. * *
  1677. * INPUT: Ptr to callback function *
  1678. * *
  1679. * OUTPUT: Nothing *
  1680. * *
  1681. * WARNINGS: None *
  1682. * *
  1683. * HISTORY: *
  1684. * 8/2/96 12:48PM ST : Documented and added WIn32 support *
  1685. *=============================================================================================*/
  1686. void NullModemClass::Setup_Modem_Echo( void ( *func )( char c) )
  1687. {
  1688. SerialPort->Set_Echo_Function(func);
  1689. //HMSetUpEchoRoutine( func );
  1690. } /* end of Setup_Modem_Echo */
  1691. /***********************************************************************************************
  1692. * NMC::Remove_Modem_Echo -- Set the echo function callback pointer to null *
  1693. * *
  1694. * *
  1695. * *
  1696. * INPUT: Nothing *
  1697. * *
  1698. * OUTPUT: Nothing *
  1699. * *
  1700. * WARNINGS: None *
  1701. * *
  1702. * HISTORY: *
  1703. * 8/2/96 12:50PM ST : Documented / Win32 support added *
  1704. *=============================================================================================*/
  1705. void NullModemClass::Remove_Modem_Echo( void )
  1706. {
  1707. SerialPort->Set_Echo_Function(NULL);
  1708. //HMSetUpEchoRoutine( NULL );
  1709. } /* end of Remove_Modem_Echo */
  1710. /***********************************************************************************************
  1711. * NMC::Print_EchoBuf -- Print out the contents of the echo buffer *
  1712. * *
  1713. * *
  1714. * *
  1715. * INPUT: Nothing *
  1716. * *
  1717. * OUTPUT: Nothing *
  1718. * *
  1719. * WARNINGS: None *
  1720. * *
  1721. * HISTORY: *
  1722. * 8/2/96 12:51PM ST : Documented *
  1723. *=============================================================================================*/
  1724. void NullModemClass::Print_EchoBuf( void )
  1725. {
  1726. for (int i = 0; i < strlen(NullModem.EchoBuf); i++) {
  1727. if (NullModem.EchoBuf[i] == '\r') {
  1728. NullModem.EchoBuf[i] = 1;
  1729. } else {
  1730. if (NullModem.EchoBuf[i] == '\n') {
  1731. NullModem.EchoBuf[i] = 2;
  1732. }
  1733. }
  1734. }
  1735. }
  1736. /***********************************************************************************************
  1737. * NMC::Reset_EchoBuf -- Empties the echo buffer *
  1738. * *
  1739. * *
  1740. * *
  1741. * INPUT: Nothing *
  1742. * *
  1743. * OUTPUT: Nothing *
  1744. * *
  1745. * WARNINGS: None *
  1746. * *
  1747. * HISTORY: *
  1748. * 8/2/96 12:51PM ST : Documented *
  1749. *=============================================================================================*/
  1750. void NullModemClass::Reset_EchoBuf( void )
  1751. {
  1752. *EchoBuf = 0;
  1753. EchoCount = 0;
  1754. }
  1755. /***********************************************************************************************
  1756. * NMC::Abort_Modem -- Checks for user input so that modem operations can be aborted *
  1757. * *
  1758. * *
  1759. * *
  1760. * INPUT: Nothing *
  1761. * *
  1762. * OUTPUT: ASUSERABORT if abort key pressed. ASSUCESS otherwise. *
  1763. * *
  1764. * WARNINGS: None *
  1765. * *
  1766. * HISTORY: *
  1767. * 8/2/96 12:52PM ST : Documented *
  1768. *=============================================================================================*/
  1769. int NullModemClass::Abort_Modem(void)
  1770. //int NullModemClass::Abort_Modem( PORT * )
  1771. {
  1772. /*........................................................................
  1773. Button Enumerations
  1774. ........................................................................*/
  1775. enum {
  1776. BUTTON_CANCEL = 100,
  1777. };
  1778. /*
  1779. ........................ Invoke game callback .........................
  1780. */
  1781. Call_Back();
  1782. /*
  1783. ........................... Get user input ............................
  1784. */
  1785. Input = Commands->Input();
  1786. switch ( Input ) {
  1787. case (KN_ESC):
  1788. case (BUTTON_CANCEL | KN_BUTTON):
  1789. return( ASUSERABORT );
  1790. }
  1791. return( ASSUCCESS );
  1792. } /* end of Abort_Modem */
  1793. /***********************************************************************************************
  1794. * NMC::Setup_Abort_Modem -- sets the modem abort function pointer *
  1795. * *
  1796. * *
  1797. * *
  1798. * INPUT: Nothing *
  1799. * *
  1800. * OUTPUT: Nothing *
  1801. * *
  1802. * WARNINGS: None *
  1803. * *
  1804. * HISTORY: *
  1805. * 8/2/96 2:59PM ST : Documented / Win32 support added *
  1806. *=============================================================================================*/
  1807. void NullModemClass::Setup_Abort_Modem( void )
  1808. {
  1809. SerialPort->Set_Abort_Function((int(*)(void))Abort_Modem);
  1810. } /* end of Setup_Abort_Modem */
  1811. /***********************************************************************************************
  1812. * NMC::Remove_Abort_Modem -- Removes the modem abort function pointer *
  1813. * *
  1814. * *
  1815. * *
  1816. * INPUT: Nothing *
  1817. * *
  1818. * OUTPUT: Nothing *
  1819. * *
  1820. * WARNINGS: None *
  1821. * *
  1822. * HISTORY: *
  1823. * 8/2/96 3:01PM ST : Documented / Win32 support added *
  1824. *=============================================================================================*/
  1825. void NullModemClass::Remove_Abort_Modem( void )
  1826. {
  1827. SerialPort->Set_Abort_Function(NULL);
  1828. } /* end of Remove_Abort_Modem */
  1829. /***********************************************************************************************
  1830. * NMC::Change_IRQ_Priority -- Increases the priority of the serial interrupt *
  1831. * *
  1832. * *
  1833. * *
  1834. * INPUT: Interrupt request number *
  1835. * *
  1836. * OUTPUT: ASSUCCESS if changed *
  1837. * *
  1838. * WARNINGS: The Win32 version of this function does nothing. *
  1839. * Priorities are controlled by windoze *
  1840. * *
  1841. * HISTORY: *
  1842. * 8/2/96 3:03PM ST : Documented / Win32 support added *
  1843. *=============================================================================================*/
  1844. int NullModemClass::Change_IRQ_Priority( int )
  1845. {
  1846. return (ASSUCCESS);
  1847. } /* end of Change_IRQ_Priority */
  1848. /***********************************************************************************************
  1849. * NMC::Get_Modem_Status -- returns status of modem control bits *
  1850. * *
  1851. * *
  1852. * *
  1853. * INPUT: Nothing *
  1854. * *
  1855. * OUTPUT: Modem status *
  1856. * *
  1857. * WARNINGS: None *
  1858. * *
  1859. * HISTORY: *
  1860. * 8/2/96 3:06PM ST : Documented / Win32 support added *
  1861. *=============================================================================================*/
  1862. int NullModemClass::Get_Modem_Status( void )
  1863. {
  1864. int modemstatus;
  1865. int status;
  1866. char buffer[81];
  1867. //modemstatus = GetModemStatus( Port );
  1868. modemstatus = SerialPort->Get_Modem_Status();
  1869. status = Send_Modem_Command( "AT", '\r', buffer, 81, DEFAULT_TIMEOUT, 1 );
  1870. if (status == MODEM_CMD_OK) {
  1871. modemstatus &= (~CD_SET);
  1872. }
  1873. return( modemstatus );
  1874. } /* end of Get_Modem_Status */
  1875. /***********************************************************************************************
  1876. * NMC::Send_Modem_Command -- Sends an 'AT' command to the modem and gets the response *
  1877. * *
  1878. * *
  1879. * *
  1880. * INPUT: command to send to modem. e.g. 'ATZ' *
  1881. * terminator byte for command string *
  1882. * buffer to put modem response into *
  1883. * length of above buffer *
  1884. * delay to wait for response *
  1885. * number of times to retry when modem doesnt respond *
  1886. * *
  1887. * OUTPUT: input delay less the time it took the modem to respond *
  1888. * *
  1889. * WARNINGS: None *
  1890. * *
  1891. * HISTORY: *
  1892. * 8/2/96 3:09PM ST : Documented / Win32 support added *
  1893. *=============================================================================================*/
  1894. int NullModemClass::Send_Modem_Command( char *command, char terminator, char *buffer, int buflen, int delay, int retries )
  1895. {
  1896. return (SerialPort->Send_Command_To_Modem(command, terminator, buffer, buflen, delay, retries));
  1897. }
  1898. /***********************************************************************************************
  1899. * NMC::Verify_And_Convert_To_Int -- converts a text string of numbers to an int *
  1900. * *
  1901. * *
  1902. * *
  1903. * INPUT: ptr to buffer *
  1904. * *
  1905. * OUTPUT: value of text number in buffer *
  1906. * *
  1907. * WARNINGS: None *
  1908. * *
  1909. * HISTORY: *
  1910. * 8/2/96 3:13PM ST : Documented *
  1911. *=============================================================================================*/
  1912. int NullModemClass::Verify_And_Convert_To_Int( char *buffer )
  1913. {
  1914. int value = 0;
  1915. int len = strlen(buffer);
  1916. for (int i = 0; i < len; i++) {
  1917. if ( !isdigit( *(buffer + i) ) ) {
  1918. value = -1;
  1919. break;
  1920. }
  1921. }
  1922. if (value == 0) {
  1923. value = atoi( buffer );
  1924. }
  1925. return( value );
  1926. } /* end of Verify_And_Convert_To_Int */
  1927. /*************************** end of nullmgr.cpp ****************************/
  1928. #endif