home *** CD-ROM | disk | FTP | other *** search
/ POINT Software Programming / PPROG1.ISO / pascal / visionix / vserhu.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1993-12-28  |  35.6 KB  |  1,275 lines

  1. {
  2.  ════════════════════════════════════════════════════════════════════════════
  3.  
  4.  Visionix Serial Communictions High-level Unit (VSERHu)
  5.    Version 0.5
  6.  Copyright 1991,92,93 Visionix
  7.  ALL RIGHTS RESERVED
  8.  
  9.  ────────────────────────────────────────────────────────────────────────────
  10.  
  11.  revision history in reverse chronological order:
  12.  
  13.  Initials  Date      Comment
  14.  
  15.  ────────  ────────  ────────────────────────────────────────────────────────
  16.  
  17.  jrt       12/06/93  Moved wait functions to here from VSeru;
  18.                      finished VSerWaitMultiSt; finished timeout code
  19.                      on all wait functions.
  20.  
  21.  jrt       12/05/93  First logged revision.
  22.  
  23.  ────────────────────────────────────────────────────────────────────────────
  24. }
  25.  
  26. (*-
  27.  
  28. [TEXT]
  29.  
  30. <Overview>
  31.  
  32. This unit implements a variety of high-level serial communications
  33. functions, which are based on the functions in VSeru.
  34.  
  35. This overview will be enhanced in the next BETA release.
  36.  
  37. <Interface>
  38.  
  39. -*)
  40.  
  41. Unit VSerHu;
  42.  
  43. Interface
  44.  
  45. Uses
  46.  
  47.   VTypesu,
  48.   VAnsiiou,
  49.   VDatesu,
  50.   VOutu,
  51.   VSeru,
  52.   VSerLu,
  53.   VStringu;
  54.  
  55.  
  56. Const
  57.  
  58.   CModemOK       = 0;
  59.   cModemNotReady = 1;
  60.  
  61.  
  62.   cWaitErr       = $FFFF;
  63.   cWaitTimeout   = $FFFE;
  64.   cWaitGood      = $0000;
  65.  
  66.  
  67. Type
  68.  
  69.   TMST = STRING[40];
  70.  
  71.   TModemDef = RECORD
  72.  
  73.     MsgGood               : TMST;           { good response after a cmd  }
  74.     MsgError              : TMST;           { error response after a cmd }
  75.     MsgNoDialtone         : TMST;           { no dialtone message        }
  76.     MsgBusy               : TMST;           { busy message               }
  77.     MsgNoAnswer           : TMST;           { no answer message          }
  78.     MsgVoice              : TMST;           { Voice answered message     }
  79.  
  80.     MsgConnect110         : TMST;           { connect rate messages      }
  81.     MsgConnect150         : TMST;
  82.     MsgConnect300         : TMST;
  83.     MsgConnect1200        : TMST;
  84.     MsgConnect2400        : TMST;
  85.     MsgConnect4800        : TMST;
  86.     MsgConnect9600        : TMST;
  87.     MsgConnect12000       : TMST;
  88.     MsgConnect14400       : TMST;
  89.     MsgConnect16800       : TMST;
  90.     MsgConnect19200       : TMST;
  91.     MsgConnect21600       : TMST;
  92.     MsgConnect24000       : TMST;
  93.     MsgConnect26800       : TMST;
  94.     MsgConnect28800       : TMST;
  95.     MsgConnect57600       : TMST;
  96.  
  97.     MsgRing               : TMST;           { phone is ringing message   }
  98.  
  99.     MsgCLIDDate           : TMST;           { Caller ID date message     }
  100.     MsgCLIDTime           : TMST;           { Caller ID time message     }
  101.     MsgCLIDPhoneNum       : TMST;           { Caller ID phone number msg }
  102.     MsgCLIDName           : TMST;           { Caller ID Name msg         }
  103.  
  104.     CmdTestReady          : TMST;           { to test if modem is ready  }
  105.     CmdReset              : TMST;           { to reset modem             }
  106.     CmdCancel             : TMST;           { to cancel a previous cmd   }
  107.  
  108.     CmdDialTone           : TMST;           { for tone dialing           }
  109.     CmdDialTonePost       : TMST;
  110.     CmdDialPulse          : TMST;           { for pulse dialing          }
  111.     CmdDialPulsePost      : TMST;
  112.  
  113.     CmdEchoOn             : TMST;           { for turning ECHO on        }
  114.     CmdEchoOff            : TMST;           { for turning ECHO off       }
  115.  
  116.     CmdSpeakerOff         : TMST;           { for turning the spkr off   }
  117.     CmdSpeakerNormal      : TMST;           { for spkr volume = normal   }
  118.     CmdSpeakerHigh        : TMST;           { for spkr volume = high     }
  119.  
  120.     CmdHangup             : TMST;           { to hangup the line         }
  121.  
  122.   END;
  123.  
  124.   PModemDef = ^TModemDef;
  125.  
  126. {────────────────────────────────────────────────────────────────────────────}
  127.  
  128.  
  129.  
  130.  
  131. {----------------------------}
  132. { Modem definition functions }
  133. {----------------------------}
  134.  
  135. Procedure VSerModemDefDefaults(   ModemDef            : PModemDef );
  136.  
  137. Function  VSerModemDefLoad(       ModemDef            : PModemDef;
  138.                                   Flags               : LONGINT;
  139.                                   DefFileName         : STRING;
  140.                                   DefName             : STRING    ) : WORD;
  141.  
  142. Function  VSerModemDial(          Chan           : TSerHandle;
  143.                                   Flags          : LONGINT;
  144.                                   NumToDial      : STRING       ) : TError;
  145.  
  146. Function  VSerModemAnswer(        Chan           : TSerHandle;
  147.                                   Flags          : LONGINT      ) : Terror;
  148.  
  149.  
  150. (*
  151.  
  152. {-------------------------}
  153. { Modem control functions }
  154. {-------------------------}
  155.  
  156. Function  VSerModemRegSet
  157.  
  158. Function  VSerModemRegGet
  159.  
  160.  
  161.  
  162. Function  VSerModemEchoOn
  163.  
  164. Function  VSerModemEchoOff
  165.  
  166. Function  VSerModemHangup
  167.  
  168. Function  VSerModemAnswer
  169.  
  170. Function  VSerModemFlowConSet
  171.  
  172. Function  VSerModemErrorConSet
  173.  
  174. Function  VSerModemCompressSet
  175.  
  176.  
  177. {-----------------------------}
  178. { transfer protocol functions }
  179. {-----------------------------}
  180.  
  181. Function  VSerProtUpload
  182.  
  183. Function  VSerProtDownload
  184.  
  185. {---------------------}
  186. { file send functions }
  187. {---------------------}
  188.  
  189. Function  VSerFileSend
  190.  
  191. *)
  192.  
  193.  
  194. {----------------}
  195. { Wait functions }
  196. {----------------}
  197.  
  198. Function  VSerWaitCh(               Chan        : TSerHandle;
  199.                                     ChToWaitFor : CHAR;
  200.                                     TimeOut100  : LONGINT;
  201.                                     CaseSense   : BOOLEAN       ) : TError;
  202.  
  203. Function  VSerWaitBlock(            Chan        : TSerHandle;
  204.                                     BlkToWaitSiz: LONGINT;
  205.                                     BlkToWaitFor: POINTER;
  206.                                     TimeOut100  : LONGINT;
  207.                                     CaseSense   : BOOLEAN       ) : TError;
  208.  
  209. Function  VSerWaitSt(               Chan        : TSerHandle;
  210.                                     StToWaitFor : STRING;
  211.                                     TimeOut100  : LONGINT;
  212.                                     CaseSense   : BOOLEAN       ) : TError;
  213.  
  214. Function  VSerWaitStMulti(          Chan        : TSerHandle;
  215.                                     TheSt1      : STRING;
  216.                                     TheSt2      : STRING;
  217.                                     TheSt3      : STRING;
  218.                                     TheSt4      : STRING;
  219.                                     TheSt5      : STRING;
  220.                                     TheSt6      : STRING;
  221.                                     TheSt7      : STRING;
  222.                                     TheSt8      : STRING;
  223.                                     TimeOut100  : LONGINT;
  224.                                     CaseSense   : BOOLEAN       ) : TError;
  225.  
  226.  
  227.  
  228. Function  VSerWaitStList(           Chan        : TSerHandle;
  229.                                     StListWait4 : PStrList;
  230.                                     STTimeOut100: LONGINT;
  231.                                     TimeOut100  : LONGINT;
  232.                                     CaseSense   : BOOLEAN       ) : TError;
  233.  
  234. {----------------}
  235. { misc functions }
  236. {----------------}
  237.  
  238. Procedure VSerAnsiOutSubChanNew(  SerChan        : TSerHandle;
  239.                                   Flags          : LONGINT;
  240.                                   SubChanName    : STRING;
  241.                                   TheOCH         : TChanHandle;
  242.                                   AddVSFilt      : BOOLEAN        );
  243.  
  244.  
  245. {────────────────────────────────────────────────────────────────────────────}
  246.  
  247. Implementation
  248.  
  249. {────────────────────────────────────────────────────────────────────────────}
  250.  
  251. (*-
  252.  
  253. [FUNCTION]
  254.  
  255. Procedure VSerModemDefDefaults(   ModemDef            : PModemDef );
  256.  
  257. [PARAMETERS]
  258.  
  259. modemdef    pointer to a variable of the type TModemDef
  260.  
  261. [RETURNS]
  262.  
  263. Nothing.
  264.  
  265. [DESCRIPTION]
  266.  
  267. This function loads the specified "ModemDef" with the default settings.
  268. These default settings should work on any strictly-Hayes compatible
  269. modem.
  270.  
  271. [SEE-ALSO]
  272.  
  273. [EXAMPLE]
  274.  
  275.  
  276.  
  277.  
  278. -*)
  279.  
  280.  
  281. Procedure VSerModemDefDefaults(   ModemDef            : PModemDef );
  282.  
  283. BEGIN
  284.  
  285.   With ModemDef^ Do
  286.   BEGIN
  287.     MsgGood              := 'OK';
  288.     MsgError             := 'ERROR';
  289.     MsgNoDialTone        := 'NO DIALTONE';
  290.     MsgBusy              := 'BUSY';
  291.     MsgNoAnswer          := 'NO CARRIER';
  292.     MsgVoice             := 'VOICE';
  293.     MsgConnect110        := 'CONNECT 110';
  294.     MsgConnect300        := 'CONNECT 300';
  295.     MsgConnect1200       := 'CONNECT 1200';
  296.     MsgConnect2400       := 'CONNECT 2400';
  297.     MsgConnect4800       := 'CONNECT 4800';
  298.     MsgConnect9600       := 'CONNECT 9600';
  299.     MsgConnect12000      := 'CONNECT 12000';
  300.     MsgConnect14400      := 'CONNECT 14400';
  301.     MsgConnect16800      := 'CONNECT 16800';
  302.     MsgConnect19200      := 'CONNECT 19200';
  303.     MsgConnect21600      := 'CONNECT 21600';
  304.     MsgConnect24000      := 'CONNECT 24000';
  305.     MsgConnect26800      := 'CONNECT 26800';
  306.     MsgConnect28800      := 'CONNECT 28800';
  307.     MsgConnect57600      := 'CONNECT 57600';
  308.     MsgRing              := 'RING';
  309.     MsgCLIDDate          := 'DATE=';
  310.     MsgCLIDTime          := 'TIME=';
  311.     MsgCLIDPhoneNum      := 'NUM =';
  312.     MsgCLIDName          := 'NAME=';
  313.  
  314.     CmdTestReady         := 'AT'+#13+#10;
  315.     CmdReset             := 'ATZ'+#13+#10;
  316.     CmdCancel            := #13+#10;
  317.     CmdDialTOne          := 'ATDT';
  318.     CmdDialTonePost      := #13+#10;
  319.     CmdDialPulse         := 'ATDP';
  320.     CmdDialPulsePost     := #13+#10;
  321.     CmdEchoOn            := 'ATE1'+#13+#10;
  322.     CmdEchoOff           := 'ATE0'+#13+#10;
  323.     CmdSpeakerOff        := 'ATM0'+#13+#10;
  324.     CmdSpeakerNormal     := 'ATM1'+#13+#10;
  325.     CmdSpeakerHigh       := 'ATM2'+#13+#10;
  326.     CmdHangup            := '~~~+++~~~ATH'+#13+#10;
  327.   END;
  328.  
  329. END; { VSerModemDefDefaults }
  330.  
  331.  
  332.  
  333. {────────────────────────────────────────────────────────────────────────────}
  334.  
  335. (*-
  336.  
  337. [FUNCTION]
  338.  
  339. Function  VSerModemDefLoad(       ModemDef            : PModemDef;
  340.                                   Flags               : LONGINT;
  341.                                   DefFileName         : STRING;
  342.                                   DefName             : STRING    ) : WORD;
  343.  
  344. [PARAMETERS]
  345.  
  346. modemdef    pointer to a variable of the type TModemDef
  347. flags       load flags (currently 0)
  348. deffilename name of the file to load the modem definition from
  349. defname     name of the modem definition
  350.  
  351. [RETURNS]
  352.  
  353. 0 if successfull, otherwise a DOS error code.
  354.  
  355. [DESCRIPTION]
  356.  
  357. This function loads the specified "ModemDef" from the definition
  358. "defname" in the defintion file "Deffilename".
  359.  
  360. THIS FUNCTION IS NOT YET IMPLEMENTED.
  361.  
  362. [SEE-ALSO]
  363.  
  364. [EXAMPLE]
  365.  
  366.  
  367.  
  368.  
  369. -*)
  370.  
  371.  
  372. Function  VSerModemDefLoad(       ModemDef            : PModemDef;
  373.                                   Flags               : LONGINT;
  374.                                   DefFileName         : STRING;
  375.                                   DefName             : STRING    ) : WORD;
  376.  
  377. BEGIN
  378.  
  379.  
  380.  
  381. END;
  382.  
  383.  
  384. {────────────────────────────────────────────────────────────────────────────}
  385.  
  386. (*
  387.  
  388. {-------------------------}
  389. { Modem control functions }
  390. {-------------------------}
  391.  
  392. Function  VSerModemRegSet
  393.  
  394. Function  VSerModemRegGet
  395.  
  396. *)
  397.  
  398.  
  399. (*-
  400.  
  401. [FUNCTION]
  402.  
  403. Function  VSerModemDial(          Chan           : TSerHandle;
  404.                                   Flags          : LONGINT;
  405.                                   NumToDial      : STRING       ) : TError;
  406.  
  407. [PARAMETERS]
  408.  
  409. chan        serial channel handle
  410. flags       dial flags (currently 0)
  411. numtodial   phone number to dial
  412.  
  413. [RETURNS]
  414.  
  415. 0 if successfull, otherwise a serial error code.
  416.  
  417. [DESCRIPTION]
  418.  
  419. This function dials the specified number "numtodial" on the specified
  420. serial channel.
  421.  
  422. [SEE-ALSO]
  423.  
  424. [EXAMPLE]
  425.  
  426.  
  427.  
  428.  
  429. -*)
  430.  
  431.  
  432.  
  433. Function  VSerModemDial(          Chan           : TSerHandle;
  434.                                   Flags          : LONGINT;
  435.                                   NumToDial      : STRING       ) : TError;
  436.  
  437. BEGIN
  438.  
  439.   { purge all input }
  440.  
  441.   VSerPurgeInBuff( Chan );
  442.  
  443.   {------------------------------------------------}
  444.   { make sure the modem is ready                   }
  445.   { by sending an AT and looking for a returned OK }
  446.   {------------------------------------------------}
  447.  
  448.   VSerWriteST( Chan, #13 );
  449.   VSerWriteST( Chan, 'AT'+#13 );
  450.  
  451.   If (VSerWaitSt( Chan, 'OK', 200, FALSE ))=0 Then
  452.   BEGIN
  453.  
  454.     VSerPurgeInBuff( Chan );
  455.  
  456.     Sleep( 200 );
  457.  
  458.     VSerWriteST( Chan, 'ATDT'+NumToDial+#13 );
  459.     VSerPurgeInBuff( Chan );
  460.  
  461.     VSerWaitStMulti( Chan,
  462.                      'NO DIALTONE',
  463.                      'BUSY',
  464.                      'NO ANSWER',
  465.                      'CONNECT',
  466.                      'NO CARRIER',
  467.                      '',
  468.                      '',
  469.                      '',
  470.                      2000,
  471.                      FALSE             );
  472.  
  473.   END
  474.   ELSE
  475.     VSerModemDial := cModemNotReady;
  476.  
  477.  
  478. END;
  479.  
  480.  
  481. Function  VSerModemAnswer(        Chan           : TSerHandle;
  482.                                   Flags          : LONGINT      ) : Terror;
  483.  
  484. BEGIN
  485.  
  486.   { purge all input }
  487.  
  488.   VSerPurgeInBuff( Chan );
  489.  
  490.   {------------------------------------------------}
  491.   { make sure the modem is ready                   }
  492.   { by sending an AT and looking for a returned OK }
  493.   {------------------------------------------------}
  494.  
  495.   VSerWriteST( Chan, #13 );
  496.   VSerWriteST( Chan, 'AT'+#13 );
  497.  
  498.   If (VSerWaitSt( Chan, 'OK', 200, FALSE ))=0 Then
  499.   BEGIN
  500.  
  501.     VSerPurgeInBuff( Chan );
  502.  
  503.     Sleep( 200 );
  504.  
  505.     Repeat
  506.     Until (VSerWaitSt( Chan, 'RING', 2000, FALSE)=0);
  507.  
  508.     VSerWriteST( Chan, 'ATA'+#13 );
  509.     VSerPurgeInBuff( Chan );
  510.  
  511.     VSerWaitStMulti( Chan,
  512.                      'NO DIALTONE',
  513.                      'BUSY',
  514.                      'NO ANSWER',
  515.                      'CONNECT',
  516.                      'NO CARRIER',
  517.                      '',
  518.                      '',
  519.                      '',
  520.                      2000,
  521.                      FALSE             );
  522.  
  523.   END
  524.   ELSE
  525.     VSerModemAnswer := cModemNotReady;
  526.  
  527.  
  528. END;
  529.  
  530.  
  531.  
  532.  
  533. (*
  534.  
  535.  
  536. Function  VSerModemEchoOn
  537.  
  538. Function  VSerModemEchoOff
  539.  
  540. Function  VSerModemHangup
  541.  
  542. {--------------------------------}
  543. { xmodem/ymodem/zmodem functions }
  544. {--------------------------------}
  545.  
  546. Function  VSerProtUpload
  547.  
  548. Function  VSerProtDownload
  549.  
  550. {---------------------}
  551. { file send functions }
  552. {---------------------}
  553.  
  554. Function  VSerFileSend
  555.  
  556. *)
  557.  
  558.  
  559. {────────────────────────────────────────────────────────────────────────────}
  560.  
  561.  
  562.  
  563. (*-
  564.  
  565. [FUNCTION]
  566.  
  567. Function  VSerWaitCh(               Chan        : TSerHandle;
  568.                                     ChToWaitFor : CHAR;
  569.                                     TimeOut100  : LONGINT;
  570.                                     CaseSense   : BOOLEAN       ) : TError;
  571.  
  572.  
  573. [PARAMETERS]
  574.  
  575. chan        serial channel handle
  576. chtowaitfor the character to wait for
  577. timeout100  how long to wait for the character (-1=no wait)
  578. casesense   TRUE if chtowaitfor case must match; FALSE if it doesn't
  579.  
  580. [RETURNS]
  581.  
  582. cWaitGood    if the character to wait for is received
  583. cWaitTimeout if the timeout value elapsed
  584. cWaitErr     if a serial error occurred.
  585.  
  586. [DESCRIPTION]
  587.  
  588. This function will wait for the character "chtowaitfor" on the specified
  589. channel, until the character is received or the "timeout100" value
  590. elapses.  If casesense is TRUE, only characters that exacly match
  591. "chToWaitFor" can end the wait.  Otherwise, any upper or lower-case
  592. character that matches can end the wait.
  593.  
  594. [SEE-ALSO]
  595.  
  596. [EXAMPLE]
  597.  
  598.   { to wait for the char 'O' for two seconds--case must match }
  599.  
  600.   Err := VSerWaitch( MyChan,
  601.                      'O',
  602.                      200,
  603.                      TRUE      );
  604.  
  605.  
  606.  
  607.   { to wait for the char 'O' for ever--case does not need to match }
  608.  
  609.   Err := VSerWaitch( MyChan,
  610.                      'O',
  611.                      -1,
  612.                      FALSE      );
  613.  
  614. -*)
  615.  
  616.  
  617. Function  VSerWaitCh(               Chan        : TSerHandle;
  618.                                     ChToWaitFor : CHAR;
  619.                                     TimeOut100  : LONGINT;
  620.                                     CaseSense   : BOOLEAN       ) : TError;
  621.  
  622. Var
  623.  
  624.   CH          : CHAR;
  625.   Err         : TError;
  626.   StartSwatch : TSwatch;
  627.  
  628. BEGIN
  629.  
  630.   StartSwatch := CurrSwatch;
  631.  
  632.   If Not CaseSense Then
  633.     ChToWaitFor := Upcase( ChToWaitFor );
  634.  
  635.   Repeat
  636.  
  637.     Err := VSerReadChEx( Chan,
  638.                          csfWait,
  639.                          CH,
  640.                          TimeOut100 );
  641.  
  642.     If Not CaseSense Then
  643.       Ch := Upcase( CH );
  644.  
  645.   Until ( Err<>0         ) or
  646.         ( CH=ChToWaitFor ) or
  647.         ( SwatchExpired( StartSwatch, Timeout100 ) );
  648.  
  649.   {---------------------------------}
  650.   { if an error, return cwait err.  }
  651.   { if a  match, return good.       }
  652.   { otherwise a timeout occured.    }
  653.   {---------------------------------}
  654.  
  655.   If Err<>0 Then
  656.     VSerWaitCH := cWaitErr
  657.   Else
  658.   If CH=ChToWaitFor Then
  659.     VSerWaitCH := cWaitGood
  660.   Else
  661.     VSerWaitCH := cWaitTimeout;
  662.  
  663. END;
  664.  
  665. {────────────────────────────────────────────────────────────────────────────}
  666.  
  667. (*-
  668.  
  669. [FUNCTION]
  670.  
  671. Function  VSerWaitBlock(            Chan        : TSerHandle;
  672.                                     BlkToWaitSiz: LONGINT;
  673.                                     BlkToWaitFor: POINTER;
  674.                                     TimeOut100  : LONGINT;
  675.                                     CaseSense   : BOOLEAN      ) : TError;
  676.  
  677. [PARAMETERS]
  678.  
  679. chan            serial channel handle
  680. blktowaitsiz    size of the block to wait for
  681. blktowaitfor    pointer to the block to wait for
  682. timeout100      timeout value
  683. timeout100      how long to wait for the block (-1=no wait)
  684. casesense       TRUE if block case must match; FALSE if it doesn't
  685.  
  686. [RETURNS]
  687.  
  688. cWaitGood    if the block to wait for is received
  689. cWaitTimeout if the timeout value elapsed
  690. cWaitErr     if a serial error occurred.
  691.  
  692. [DESCRIPTION]
  693.  
  694. This function will wait for the block "blktowaitfor" on the specified
  695. channel, until the block is received or the "timeout100" value
  696. elapses.  If casesense is TRUE, only sequential characters that exactly match
  697. "blktowaitfor" can end the wait.  Otherwise, any upper or lower-case
  698. sequential characters that match the block can end the wait.
  699.  
  700. [SEE-ALSO]
  701.  
  702. [EXAMPLE]
  703.  
  704.   { to wait for the block 'EMSI' for 2 seconds--case must match }
  705.  
  706.   Buff[0] := 'E';
  707.   Buff[1] := 'M';
  708.   Buff[2] := 'S';
  709.   Buff[3] := 'I';
  710.  
  711.   Err := VSerWaitBlock( MyChan,
  712.                         4,
  713.                         @Buff,
  714.                         200,
  715.                         TRUE       );
  716.  
  717.  
  718.  
  719.   { to wait for the block 'EMS' forever --case need not match }
  720.  
  721.   Err := VSerWaitBlock( Mycyan,
  722.                         4,
  723.                         @Buff,
  724.                         -1,
  725.                         FALSE       );
  726.  
  727. -*)
  728.  
  729.  
  730. Function  VSerWaitBlock(            Chan        : TSerHandle;
  731.                                     BlkToWaitSiz: LONGINT;
  732.                                     BlkToWaitFor: POINTER;
  733.                                     TimeOut100  : LONGINT;
  734.                                     CaseSense   : BOOLEAN      ) : TError;
  735.  
  736. Var
  737.  
  738.   MatchCount        : LONGINT;
  739.   Err               : TError;
  740.   CH                : CHAR;
  741.   StartSwatch       : TSwatch;
  742.  
  743. BEGIN
  744.  
  745.   StartSwatch := CurrSwatch;
  746.  
  747.   MatchCount := 0;
  748.  
  749.   {-------------------------------------------------}
  750.   { repeat until we find a match or an error occurs }
  751.   { or the timeout expires.                         }
  752.   {-------------------------------------------------}
  753.  
  754.  
  755.   Repeat
  756.  
  757.     {----------------------------------------------}
  758.     { Get a character, make sure their is no error }
  759.     {----------------------------------------------}
  760.  
  761.     Err := VSerReadChEx( Chan, csfWait, CH, Timeout100 );
  762.  
  763.     If Err=0 Then
  764.     BEGIN
  765.  
  766.         {------------------------------------------------------------}
  767.         { for this block:  see if we have a match.  If so, increment }
  768.         { the match count.  If not, reset the match count.  If the # }
  769.         { of matches on this block  = the length of the block , we   }
  770.         { have a block  match.                                       }
  771.         {------------------------------------------------------------}
  772.  
  773.  
  774.       IF CaseSense Then
  775.       BEGIN
  776.         If PCharArray( BlkToWaitFor )^[ Pred( MatchCount )] = Ch Then
  777.           Inc( MatchCount )
  778.         Else
  779.           MatchCount := 0;
  780.       END
  781.       ELSE
  782.       BEGIN
  783.         If UpCase(PCharArray( BlkToWaitFor )^[ Succ( MatchCount )]) =
  784.            UpCase( Ch ) Then
  785.           Inc( MatchCount )
  786.         Else
  787.           MatchCount := 0;
  788.       END; { if casesense / else }
  789.  
  790.     END; { if err=0 }
  791.  
  792.   Until ( Err<>0                                   ) or
  793.         ( MatchCount=BlkToWaitSiz                  ) or
  794.         ( SwatchExpired( StartSwatch, TimeOut100 ) );
  795.  
  796.  
  797.   {---------------------------------}
  798.   { if an error, return cwait err.  }
  799.   { if a  match, return good.       }
  800.   { otherwise a timeout occured.    }
  801.   {---------------------------------}
  802.  
  803.   If Err<>0 Then
  804.     VSerWaitBlock := cWaitErr
  805.   Else
  806.   If MatchCount=BlkToWaitSiz Then
  807.     VSerWaitBlock := cWaitGood
  808.   Else
  809.     VSerWaitBlock := cWaitTimeout;
  810.  
  811.  
  812. END;
  813.  
  814. {────────────────────────────────────────────────────────────────────────────}
  815.  
  816.  
  817. (*-
  818.  
  819. [FUNCTION]
  820.  
  821. Function  VSerWaitSt(               Chan        : TSerHandle;
  822.                                     StToWaitFor : STRING;
  823.                                     TimeOut100  : LONGINT;
  824.                                     CaseSense   : BOOLEAN       ) : TError;
  825.  
  826. [PARAMETERS]
  827.  
  828. chan            serial channel handle
  829. sttowaitfor     string to wait for
  830. timeout100      how long to wait for the block (-1=no wait)
  831. casesense       TRUE if string case must match; FALSE if it doesn't
  832.  
  833. [RETURNS]
  834.  
  835. cWaitGood    if the string to wait for is received
  836. cWaitTimeout if the timeout value elapsed
  837. cWaitErr     if a serial error occurred.
  838.  
  839. [DESCRIPTION]
  840.  
  841. This function will wait for the string "sttowaitfor" on the specified
  842. channel, until the string is received or the "timeout100" value
  843. elapses.  If casesense is TRUE, only sequential characters that exactly match
  844. "sttowaitfor" can end the wait.  Otherwise, any upper or lower-case
  845. sequential characters that match the string can end the wait.
  846.  
  847. [SEE-ALSO]
  848.  
  849. [EXAMPLE]
  850.  
  851.   { to wait for the string 'Please Logon:' for 2 seconds--case must match }
  852.  
  853.   Err := VSerWaitString( MyChan,
  854.                          'Please Logon:',
  855.                          200,
  856.                          TRUE       );
  857.  
  858.  
  859.   { to wait for the string 'Please Logon:' forever--case need not match }
  860.  
  861.   Err := VSerWaitString( MyChan,
  862.                          'Please Logon:',
  863.                          -1,
  864.                          FALSE               );
  865.  
  866.  
  867. -*)
  868.  
  869. Function  VSerWaitSt(               Chan        : TSerHandle;
  870.                                     StToWaitFor : STRING;
  871.                                     TimeOut100  : LONGINT;
  872.                                     CaseSense   : BOOLEAN       ) : TError;
  873.  
  874. BEGIN
  875.  
  876.   VSerWaitSt := VSerWaitBlock( Chan,
  877.                                Byte( StToWaitFor[ 0 ] ),
  878.                                @StToWaitFor[1],
  879.                                Timeout100,
  880.                                CaseSense                        );
  881.  
  882. END;
  883.  
  884. {────────────────────────────────────────────────────────────────────────────}
  885.  
  886. (*-
  887.  
  888. [FUNCTION]
  889.  
  890. Function  VSerWaitStMulti(          Chan        : TSerHandle;
  891.                                     TheSt1      : STRING;
  892.                                     TheSt2      : STRING;
  893.                                     TheSt3      : STRING;
  894.                                     TheSt4      : STRING;
  895.                                     TheSt5      : STRING;
  896.                                     TheSt6      : STRING;
  897.                                     TheSt7      : STRING;
  898.                                     TheSt8      : STRING;
  899.                                     TimeOut100  : LONGINT;
  900.                                     CaseSense   : BOOLEAN       ) : TError;
  901.  
  902. [PARAMETERS]
  903.  
  904. chan            serial channel handle
  905. TheSt1          string #1 to wait for
  906. TheSt2          string #2 to wait for
  907. TheSt3          string #3 to wait for
  908. TheSt4          string #4 to wait for
  909. TheSt5          string #5 to wait for
  910. TheSt6          string #6 to wait for
  911. TheSt7          string #7 to wait for
  912. TheSt8          string #8 to wait for
  913. timeout100      how long to wait for the block (-1=no wait)
  914. casesense       TRUE if string case must match; FALSE if it doesn't
  915.  
  916. [RETURNS]
  917.  
  918. 1-8          if the string #x was received
  919. cWaitTimeout if the timeout value elapsed
  920. cWaitErr     if a serial error occurred.
  921.  
  922. [DESCRIPTION]
  923.  
  924. This function will wait for any one of 8 specified strings on the specified
  925. channel, until the one of thestrings is received or the "timeout100" value
  926. elapses.  If casesense is TRUE, only sequential characters that exactly match
  927. one of the strings can end the wait.  Otherwise, any upper or lower-case
  928. sequential characters that match one of the strings can end the wait.
  929.  
  930. [SEE-ALSO]
  931.  
  932. [EXAMPLE]
  933.  
  934.   { to wait for either 'Please Logon:', 'Enter your name:', or  }
  935.   { 'uucp!Login:' for 2 seconds--case must match                }
  936.  
  937.   Err := VSerWaitStMulti( Mychan,
  938.                           'Please Logon:',
  939.                           'Enter your name:',
  940.                           'uucp!Login:',
  941.                           '',
  942.                           '',
  943.                           '',
  944.                           '',
  945.                           '',
  946.                           200,
  947.                           TRUE                    );
  948.  
  949.   { to wait for either 'Please Logon:', 'Enter your name:', or  }
  950.   { 'uucp!Login:' forever -- case need not match                }
  951.  
  952.   Err := VSerWaitStMulti( Mychan,
  953.                           'Please Logon:',
  954.                           'Enter your name:',
  955.                           'uucp!Login:',
  956.                           '',
  957.                           '',
  958.                           '',
  959.                           '',
  960.                           '',
  961.                           -1,
  962.                           FALSE                 );
  963.  
  964. -*)
  965.  
  966.  
  967. Function  VSerWaitStMulti(          Chan        : TSerHandle;
  968.                                     TheSt1      : STRING;
  969.                                     TheSt2      : STRING;
  970.                                     TheSt3      : STRING;
  971.                                     TheSt4      : STRING;
  972.                                     TheSt5      : STRING;
  973.                                     TheSt6      : STRING;
  974.                                     TheSt7      : STRING;
  975.                                     TheSt8      : STRING;
  976.                                     TimeOut100  : LONGINT;
  977.                                     CaseSense   : BOOLEAN       ) : TError;
  978.  
  979.  
  980. Var
  981.  
  982.   TheString   : Array[1..8] of PSTRING;
  983.   MatchCount  : Array[1..8] of BYTE;
  984.   Z           : INTEGER;
  985.   Err         : TError;
  986.   CH          : CHAR;
  987.   Done        : BOOLEAN;
  988.   StartSwatch : TSwatch;
  989.  
  990. BEGIN
  991.  
  992.   StartSwatch := CurrSwatch;
  993.  
  994.   {------------------------}
  995.   { setup the pointer list }
  996.   {------------------------}
  997.  
  998.   TheString[1] := @TheSt1;
  999.   TheString[2] := @TheSt2;
  1000.   TheString[3] := @TheSt3;
  1001.   TheString[4] := @TheSt4;
  1002.   TheString[5] := @TheSt5;
  1003.   TheString[6] := @TheSt6;
  1004.   TheString[7] := @TheSt7;
  1005.   TheString[8] := @TheSt8;
  1006.  
  1007.   For Z := 1 to 8 Do
  1008.     MatchCount[Z] := 0;
  1009.  
  1010.   {-------------------------------------------------}
  1011.   { repeat until we find a match or an error occurs }
  1012.   { or the timeout expires.                         }
  1013.   {-------------------------------------------------}
  1014.  
  1015.   Done := FALSE;
  1016.  
  1017.   Repeat
  1018.  
  1019.     {----------------------------------------------}
  1020.     { Get a character, make sure their is no error }
  1021.     {----------------------------------------------}
  1022.  
  1023.     Err := VSerReadChEx( Chan, csfwait, CH, timeout100 );
  1024.  
  1025.     If Err=0 Then
  1026.     BEGIN
  1027.  
  1028.       {---------------------------------------------------------}
  1029.       { loop through each string and see if we have a match yet }
  1030.       {---------------------------------------------------------}
  1031.  
  1032.       Z := 0;
  1033.  
  1034.       Repeat
  1035.  
  1036.         Inc( Z );
  1037.  
  1038.         {------------------------------------------------------------}
  1039.         { for each string, see if we have a match.  If so, increment }
  1040.         { the match count.  If not, reset the match count.  If the # }
  1041.         { of matches on this string = the length of the string, we   }
  1042.         { have a string match.                                       }
  1043.         {------------------------------------------------------------}
  1044.  
  1045.         If CaseSense Then
  1046.         BEGIN
  1047.  
  1048.           If ( MatchCount[Z] < Length(TheString[Z]^)           ) And
  1049.              ( TheString[Z]^[ Succ( MatchCount[Z] ) ] = Ch     ) Then
  1050.           BEGIN
  1051.             Inc( MatchCount[Z] );
  1052.             Done := ( MatchCount[Z]=Length( TheString[Z]^ ) );
  1053.           END
  1054.           Else
  1055.             MatchCount[Z] := 0;
  1056.  
  1057.         END    { if casesense }
  1058.         ELSE
  1059.         BEGIN
  1060.  
  1061.           If ( MatchCount[Z] < Length(TheString[Z]^)              ) And
  1062.              ( UpCase( TheString[Z]^[ Succ( MatchCount[Z] ) ] ) =
  1063.                  UpCase( Ch )                                     ) Then
  1064.           BEGIN
  1065.             Inc( MatchCount[Z] );
  1066.             Done := ( MatchCount[Z]=Length( TheString[Z]^ ) );
  1067.           END
  1068.           Else
  1069.             MatchCount[Z] := 0;
  1070.  
  1071.         END; { if casesense / else }
  1072.  
  1073.       Until (Z=8) or (Done);
  1074.  
  1075.     END; { if err=0 }
  1076.  
  1077.   Until ( Err<>0                                   ) or
  1078.         ( Done                                     ) or
  1079.         ( SwatchExpired( StartSwatch, Timeout100 ) );
  1080.  
  1081.  
  1082.   {----------------------------------------}
  1083.   { if an error, return cwait err.         }
  1084.   { if a  match, return which one matched. }
  1085.   { otherwise a timeout occured.           }
  1086.   {----------------------------------------}
  1087.  
  1088.   If Err<>0 Then
  1089.     VSerWaitStMulti := cWaitErr
  1090.   Else
  1091.   If Done Then
  1092.     VSerWaitStMulti := Z
  1093.   Else
  1094.     VSerWaitStMulti := cWaitTimeout;
  1095.  
  1096.  
  1097. END; { function VSerWaitStMulti }
  1098.  
  1099. {────────────────────────────────────────────────────────────────────────────}
  1100.  
  1101.  
  1102. (*-
  1103.  
  1104. [FUNCTION]
  1105.  
  1106. Function  VSerWaitStList(           Chan        : TSerHandle;
  1107.                                     StListWait4 : PStrList;
  1108.                                     STTimeOut100: LONGINT;
  1109.                                     TimeOut100  : LONGINT;
  1110.                                     CaseSense   : BOOLEAN       ) : TError;
  1111.  
  1112. [PARAMETERS]
  1113.  
  1114. chan            serial channel handle
  1115. stlistwait4     string-list to wait for
  1116. timeout100      how long to wait for the block (-1=no wait)
  1117. casesense       TRUE if string case must match; FALSE if it doesn't
  1118.  
  1119. [RETURNS]
  1120.  
  1121. 1-32768      if the string #x was received
  1122. cWaitTimeout if the timeout value elapsed
  1123. cWaitErr     if a serial error occurred.
  1124.  
  1125. [DESCRIPTION]
  1126.  
  1127. This function will wait for any one of x specified strings on the specified
  1128. channel, until the one of the strings is received or the "timeout100" value
  1129. elapses.  If casesense is TRUE, only sequential characters that exactly match
  1130. one of the strings can end the wait.  Otherwise, any upper or lower-case
  1131. sequential characters that match one of the strings can end the wait.
  1132.  
  1133. THIS FUNCTION IS NOT YET IMPLEMENTED!
  1134.  
  1135. [SEE-ALSO]
  1136.  
  1137. [EXAMPLE]
  1138.  
  1139.  
  1140. -*)
  1141.  
  1142. Function  VSerWaitStList(           Chan        : TSerHandle;
  1143.                                     StListWait4 : PStrList;
  1144.                                     STTimeOut100: LONGINT;
  1145.                                     TimeOut100  : LONGINT;
  1146.                                     CaseSense   : BOOLEAN       ) : TError;
  1147.  
  1148. BEGIN
  1149.  
  1150. END;
  1151.  
  1152. {────────────────────────────────────────────────────────────────────────────}
  1153.  
  1154. Procedure SerSendSt(              IData          : PAnsiOutDriverIdata;
  1155.                               Var ST             : STRING               ); Far;
  1156.  
  1157. BEGIN
  1158.  
  1159.   { Param 3 = Serial channel handle }
  1160.  
  1161.   While VSerGetOutFree( Pointer(Idata^.Param3) )<2048 Do;
  1162.  
  1163.   VSerWriteST( Pointer(IData^.Param3), ST );
  1164.  
  1165. END;
  1166.  
  1167.  
  1168. {────────────────────────────────────────────────────────────────────────────}
  1169.  
  1170. (*-
  1171.  
  1172. [FUNCTION]
  1173.  
  1174. Procedure VSerAnsiOutSubChanNew(  SerChan        : TSerHandle;
  1175.                                   Flags          : LONGINT;
  1176.                                   SubChanName    : STRING;
  1177.                                   TheOCH         : TChanHandle;
  1178.                                   AddVSFilt      : BOOLEAN        );
  1179.  
  1180.  
  1181. [PARAMETERS]
  1182.  
  1183. serchan     serial channel handle
  1184. flags       currently 0
  1185. subchanname name of the new sub-channel
  1186. theoch      handle of the channel to create the sub-channel off of
  1187. addvsfilt   TRUE if the virtual screen filter should be attached
  1188.             to the new channel, FALSE if it should not.
  1189.  
  1190. [RETURNS]
  1191.  
  1192. Nothing.
  1193.  
  1194. [DESCRIPTION]
  1195.  
  1196. This function will create a new-sub channel named "subchanname" off of the
  1197. channel associate with "theoch".  The new channel will use the
  1198. AnsiOutDriverProc to create ANSI commands and send them to the serial
  1199. channel associated with "serchan".
  1200.  
  1201. If AddVSFilt is TRUE, the virtual-screen filter will be attached to this
  1202. new out-channel.  The virtual screen filter is required if you intend
  1203. to use the window or any of the region commands on the new channel.
  1204. The virutal screen filter keeps a virtual image of the remote screen.
  1205. If you do not need to use the Window or any of the region commands, you
  1206. do not need to attach the virtual screen filter.
  1207.  
  1208. What the heck does all that mean?
  1209. --------------------------------
  1210.  
  1211. By calling this function and specifying the CRTs outout channel handle
  1212. as "theoch", this function will create a sub-channel which will send
  1213. ANSI commands out the specified serial channel when you call GotoXY,
  1214. TextColor, ClrScr, Write, etc.  VCRT functions.
  1215.  
  1216. [SEE-ALSO]
  1217.  
  1218. [EXAMPLE]
  1219.  
  1220.   { to create a serial-ansi sub-channel on VCRTs output channel }
  1221.  
  1222.   VSerAnsiOutSubChanNew( MySerChan,
  1223.                          0,
  1224.                          'ANSISERCHAN',
  1225.                          CrtOCH,
  1226.                          TRUE                   );
  1227.  
  1228. -*)
  1229.  
  1230. Procedure VSerAnsiOutSubChanNew(  SerChan        : TSerHandle;
  1231.                                   Flags          : LONGINT;
  1232.                                   SubChanName    : STRING;
  1233.                                   TheOCH         : TChanHandle;
  1234.                                   AddVSFilt      : BOOLEAN        );
  1235.  
  1236. BEGIN
  1237.  
  1238.   {---------------------------------------------------------}
  1239.   { Create a new sub-channel off of the specified channel.  }
  1240.   { Make the anchor driver the ANSI out driver, and tell it }
  1241.   { to send all output to custom ansi output routine: our   }
  1242.   { local SerSendSt procedure.                              }
  1243.   {---------------------------------------------------------}
  1244.  
  1245.   VOutSubChannelNew( TheOCH,
  1246.                      0,
  1247.                      SubChanName,
  1248.                      ANSIOutDriverProc,
  1249.                      caoCustom,
  1250.                      Longint(@SerSendSt),
  1251.                      Longint(SerChan)        );
  1252.  
  1253.   If AddVSFilt Then
  1254.     VOutFilterAttach( TheOCH,
  1255.                       0,
  1256.                       'VSFILT',
  1257.                       SubChanName,
  1258.                       VirtScreenFilter,
  1259.                       0, 0, 0                );
  1260.  
  1261.  
  1262. END;
  1263.  
  1264. {────────────────────────────────────────────────────────────────────────────}
  1265.  
  1266.  
  1267.  
  1268. {────────────────────────────────────────────────────────────────────────────}
  1269. {────────────────────────────────────────────────────────────────────────────}
  1270. {────────────────────────────────────────────────────────────────────────────}
  1271. {────────────────────────────────────────────────────────────────────────────}
  1272.  
  1273. BEGIN
  1274. END.
  1275.