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