


Program SpeakNow;
 (*     				Speak Now
 			Modem Communications program
 
                         	Jeff Talbot
                                 Greg Whitsitt
                                 Bryan Rex
                                 Kyle Lutz
 
                         Last Modified: April 24, 1995
 							            *)
 
 
 
 uses Wincrt,WinProcs,WinTypes,WinDos;
 
 CONST enter = Chr(13);	 (* Enter Key ascii character, used for 
sending
 			    a command to the modem since the modem will
                             execute a command only when enter is pressed *)
 Type
     PcharType = ARRAY[0..39] OF CHAR;
 
 Var
    outpt, Fv : TEXT;		(* output window; file var	    *)
    Port : TDCB;			(* The comm port variable	    *)
    choice : CHAR;		(* User choice from menu   	    *)
    PortHandle, w : INTEGER;	(* Handle used to refer to the port *)
 
 
 PROCEDURE Setup(VAR outpt:TEXT; VAR Port:TDCB; VAR 
PortHandle:INTEGER);
 VAR	Comm : ARRAY[0..10] OF CHAR;
         ComNo: CHAR;
         Prev:STRING;
         x : INTEGER;
 
 BEGIN
   ASSIGNCRT(outpt);
   ASSIGN(Fv,'C:\SPEAK\SETTINGS.DAT');
   RESET(Fv);
   REWRITE(outpt);
   READLN(Fv, ComNo);
   Prev := 'COM';
   Prev := Prev + ComNo;
   FOR x := 1 TO LENGTH(Prev) DO
     Comm[x - 1] := Prev[x];
   REPEAT
     PortHandle := OpenComm(Comm,100,100);
   UNTIL PortHandle  ie_NOpen;
 
   IF PortHandle < 0 THEN BEGIN
     WRITELN(outpt, 'Error in preparing communication port:');
     WRITELN(outpt, 'Error Code: ', PortHandle);
     CASE PortHandle OF
     ie_Hardware:
       WRITELN(outpt, '	You do not have a modem connected to com',
     	ComNo, '.');
     ie_Open:
       WRITELN(outpt, '	Com', ComNo, ' is already open. Unable to',
       		' assign it a handle.');
     -1:
       WRITELN(outpt, 'You have not specified a valid Comm port in 
your settings.dat file.');
     END;
     WRITELN;
     WRITELN('Sorry, SpeakNow cannot run.');
     HALT;
   END;
 
   WriteComm(PortHandle, 'ATV0', 4); (* have modem send back
   				       numeric result codes *)
   WriteComm(PortHandle, 'E0', 2);   (* turn echo off *)
   WriteComm(PortHandle, '\C1', 3);  (* buffer	     *)
   WriteComm(PortHandle, 'S7=30', 5);(* time to wait for carrier
   				       after dialing *)
   WriteComm(PortHandle, 'X3', 2);   (* tells the modem to respond
   				       with result codes 0 - 5, 7, & 9 - 20
                                        when connecting to remote modem *)
   WriteComm(PortHandle, 'S8=03', 5);(* delay for each comma *)
   WriteComm(PortHandle, enter, 1);  (* execute all commands *)
 
     {READLN(Fv, Id);
     READLN(Fv, Baudrate);
     READLN(Fv, ByteSize);
     READLN(Fv, Parity);
     READLN(Fv, Stopbits);
     READLN(Fv, RlsTimeout);
     READLN(Fv, CtsTimeout);
     READLN(Fv, DsrTimeout);
     READLN(Fv, Flags);		(* need to add later *)
     READLN(Fv, XonChar);
     READLN(Fv, XoffChar);
     READLN(Fv, XonLim);
     READLN(Fv, XoffLim);
     READLN(Fv, PeChar);
     READLN(Fv, EofChar);
     READLN(Fv, EvtChar);
     READLN(Fv, TxDelay);}
 END;
 
 
 PROCEDURE Menu(VAR choice:CHAR);
 BEGIN
   CLRSCR;
   WRITELN('***** Thank You For Using SpeakNow *****');
   WRITELN;
   WRITELN('Please Enter Your Selection: ');
   WRITELN;
   WRITELN('(D)':8, '  Dial the other modem');
   WRITELN('(A)':8, '  Answer the other modem');
   WRITELN('(E)':8, '  Edit terminal settings');
   WRITELN('(Q)':8, '  Quit SpeakNow');
   REPEAT
     choice := READKEY;
     choice := UPCASE(choice);
   UNTIL choice IN ['D', 'A', 'E', 'Q'];
 END;
 
 Procedure Menu2(Var Second:CHAR);
 Var {Temp,}Path:String;
 {    d : array[0..fsPathName] of Char;	}
 {    Question:Char;			}
 
 Begin
   ClrScr;
   WriteLn('Please Enter Your Next Selection');
   WriteLn;
   WriteLn('[S] I will send a sound file to the other modem');
   WriteLn('[R] I will receive a sound file from the other modem.');
   Repeat
     Second := ReadKey;
     Second := UpCase(Second);
   Until Second In ['S', 'R'];
 End;
 
 PROCEDURE Dial(PortHandle:INTEGER);
 VAR	x, numb, result:INTEGER;
 	time : LONGINT;
         dial, input, num:STRING;
         dialcommand : PcharType;
         p : Pchar;
         c : CHAR;
         ok : BOOLEAN;
 
 BEGIN
    CLRSCR;
    WRITE(outpt, 'Number to call: ');
    READLN(input);
    num := '';
    FOR x := 1 TO LENGTH(input) DO
      IF input[x] IN ['0'..'9'] THEN num := num + input[x];
    dial := 'ATDT'+num+enter;
    FOR x := 1 TO LENGTH(dial) DO
      dialcommand[x - 1] := dial[x];
    p := Addr(c);
 
      REPEAT
      WRITELN(outpt, 'Dialing ', num, '...');
      x := WriteComm(PortHandle, dialcommand, LENGTH(dial));
      ok := (x > 0);
      IF ok THEN BEGIN
        ok := FALSE;
        REPEAT
          x := ReadComm(PortHandle, p, 1);
          val(p^, result, numb);
        UNTIL (result > 0) AND (result  2);
        CASE result OF
          1, 5, 10..20: ok := TRUE;
          3: WRITELN(outpt, 'No carrier.');
          4: WRITELN(outpt, 'Error in connection.');
          7: WRITELN(outpt, 'Busy signal.');
        END;
      END;
      IF NOT ok THEN BEGIN
        WriteComm(PortHandle, 'ATH', 3);
        WriteComm(PortHandle, enter, 1);
        time := GetTickCount;
        WHILE (GetTickCount - time) < 1000 DO x:=0;
      END;
    UNTIL ok;
 END;
 
 PROCEDURE Answer(PortHandle:INTEGER; VAR w:INTEGER);
 VAR x, result, num:Integer;
     c: CHAR;
     q: POINTER;
     p:Pchar;
 
 BEGIN
   WriteComm(PortHandle, 'ATS0=1'+enter, 7);
   w := 0;
   CLRSCR;
   WHILE (w = 0) DO BEGIN
     CURSORTO(0, 0);
     WRITELN('Waiting for a signal from remote modem...');
     x := GetKeyState(VkKeyScan(27));
     IF HI(x)  0 THEN w := 1;
     p := Addr(c);
     ReadComm(PortHandle, p, 1);
     val(p^, result, num);
     IF (result IN [10..20]) OR (result = 5) THEN w := 2;
   END;
 END;
 
 PROCEDURE Edit_Term(PortHandle:INTEGER; VAR Port:TDCB; VAR 
outpt:TEXT);
 VAR	x:INTEGER;
 BEGIN
   CLRSCR;
   WRITELN(outpt, 'Current Terminal Settings:');
   WRITELN;
   x := GetCommState(PortHandle, Port);
   IF x = 0 THEN BEGIN
     CLRSCR;
     WITH Port DO BEGIN
       WRITELN('Baud Rate:', Baudrate:10);
       WRITELN('Bits per character:', ByteSize:10);
       WRITELN('Parity:', Parity:10);
       WRITELN('Stop Bits:',Stopbits:10);
       WRITELN(RlsTimeout);
       WRITELN(CtsTimeout);
       WRITELN(DsrTimeout);
       WRITELN(Flags);
       WRITELN(XonChar);
       WRITELN(XoffChar);
       WRITELN(XonLim);
       WRITELN(XoffLim);
       WRITELN(PeChar);
       WRITELN(EofChar);
       WRITELN(EvtChar);
       WRITELN(TxDelay);
     END;
     READLN;
   END;
 END;
 
 PROCEDURE SEND(PortHandle:INTEGER);
 VAR  Fv : TEXT;
      path:STRING;
      data:Char;
 
 BEGIN
   Clrscr;
   WRITE('Give the file you are sending: ');
   READLN(path);
   ASSIGN(Fv,path);
   RESET(Fv);
   FlushComm(PortHandle, 0);
   WRITELN('Sending ready signal to remote modem...');
   TransmitCommChar(PortHandle, 'B');
   FlushComm(PortHandle, 0);
   WRITELN('Sending data to remote modem...');
 
   WHILE NOT (EOF(Fv)) AND ((data  'Q')) DO BEGIN
     WHILE NOT EOLN(Fv) DO BEGIN
       READ(Fv, data);
       WRITE(data);
       TransmitCommChar(PortHandle, data);
     END;
     READLN(Fv);
     WRITELN;
   END;
   CLOSE(Fv);
   WRITELN;
   WRITELN('----------------- End of Transmission -----------------');
   data := READKEY;
 END;
 
 PROCEDURE RECEIVE(VAR Fv:TEXT; PortHandle:INTEGER);
 VAR  p:Pchar;
      fle:STRING;
      data:Char;
 BEGIN
   CLRSCR;	(* CLEAR SCREEN *)
   WRITE('What file are you receiving? : ');
   READLN(fle);  (* GET FILE NAME *)
   ASSIGN(Fv, fle); (* PUT INTO TEXT VAR *)
   RESET(Fv);    (* RESET THE FILE *)
   REWRITE(Fv);	(* OPEN THE FILE FOR WRITING *)
   p:=addr(data);
   REPEAT
     ReadComm(PortHandle, p, 1);
   UNTIL data = 'B';
   REPEAT
     ReadComm(PortHandle, p, 1);
     WRITE(data);
     WRITE(Fv, data);
   UNTIL data = 'Q';
   Close(Fv);
 END;
 
 PROCEDURE SPEAK(PortHandle:INTEGER);
 VAR Second:CHAR;
 BEGIN
   WriteLn('Connected.');
   Menu2(Second);
   CLRSCR;
   CASE Second OF
   'S': Send(PortHandle);
   'R': Receive(Fv, PortHandle);
 
 
 BEGIN	(* SpeakNow MAIN *)
   (* setup variables & configure comm port *)
   Setup(outpt, Port, PortHandle);
 
   REPEAT
     Menu(choice);		  (* let user make a selection *)
     CASE choice OF
     'D': BEGIN			  (* D is for Dial *)
            Dial(PortHandle);	  (* call the Dial procedure *)
            Speak(PortHandle);	  (* call the Speak procedure *)
          END;			  (* end dialing choice	*)
 
     'A': BEGIN			  (* A is for Answer *)
            Answer(PortHandle, w); (* call the Answer procedure *)
            IF w = 2 THEN Speak(PortHandle); (* call the Speak procedure 
*)
          END;			  (* end answer choice *)
 
     'E':Edit_Term(PortHandle, Port, outpt); (* E is for edit terminal *)
     END;  			  (* end case for selection *)
   UNTIL choice = 'Q';		  (* run menu until Quit is chosen *)
 
   CloseComm(PortHandle);	  (* close the comm port *)
   DoneWinCrt;			  (* close the output window *)
   WriteComm(PortHandle, 'AT H'+enter, 5);
 END.				  (* end SpeakNow *)
 
 



