  Programming Notes                                    A WindoWatch feature

                         Window Aspect: A Scripting Language
                         A Tutorial: Part Six Ghost BBS v3.20
                            Copyright 1995 by Gregg Hommel


 I want to digress in this column from our discussions on using an INI
 file, to that of a problem that I ran into recently with GHOST BBS 3.21
 alpha. The actual problem and it's solution are not the point, but how I
 discovered what the problem was and what represented its solution, I
 think you will find interesting . The point of the discussion rests in
 the theory and practice that were used to uncover the problem, and then
 fix it.  It is this information that can be quite valuable to you when
 scripting, and, in my opinion, makes this column worthwhile....

 I had modified some code in GHOST BBS as Im working on 3.21 alpha,
 to improve the functioning and speed of opening and closing DOS doors. My
 original GHOST BBS 3.10/3.20 code had several pauses placed in it, to
 allow the modem time to get set, or so I thought. I wanted to test that
 theory, and lower or eliminate, those pauses to make opening and closing
 a door faster.

 At first, it appeared that no pauses at all were needed. I had eliminated
 them, and GHOST opened and closed the DOS doors on my system without any
 problems, - until I threw Adaptive Answer and fax into the mix!

 You see, before I released GHOST 3.20, I had never actually tested
 GHOST'S use with Adaptive Answer enabled for incoming fax calls myself.
 I couldn't because I didn't have a fax modem. My venerable old ZOOM 9600
 Turbo was doing just fine, and in truth, I didn't want to have a fax on
 my computer. But my GHOST beta sites wanted Adaptive Answer, so I wrote
 the code, without testing it myself, and let them do it for me.  Never
 will I do that again! Even so, Adaptive Answer support didn't turn out to
 be all that complicated, and eventually, we got it working.

 The GHOST 3.20 users along with beta sites were asking if I planned on
 adding fax back functionality to GHOST 3.20!  No way was I going to write
 such code without a fax modem.  In the shareware world one simply can't
 ignore the vox populi.  The obvious solution  was the purchase of  a fax
 modem that supported Adaptive Answer to test GHOST current and future
 features .. and so I did <sigh>.

 It turned out that DOS doors appeared to function perfectly without any
 PAUSE commands in the code, when Adaptive Answer was not functioning.
 However, the same could not be said of the doors when it was enabled.
 Their operation became inconsistent, and unreliable which sent me looking
 for the cause....

 I noticed that when I opened a door from a remote site, with Adaptive
 Answer enabled, I never saw when Adaptive Answer was disabled.  I kept
 seeing, on the remote screen, a string that that made me certain that
 GHOST was not sending.  The string ATS0=0, which, if you know Hayes modem
 commands, is one that turns off autoanswer in the modem.

 This really confused me, as I knew that in my PCP/Win set up, that string
 location was empty, i.e. there was nothing stored there,  that GHOST was
 not sending the string, and finally, PCP/Win 2.xx does not use the S0
 register to control autoanswer, the string I was seeing was completely
 useless.

 However, I do know enough about modems to know that if you send such a
 string to the modem, while carrier is high, i.e. while on-line, whatever
 comm application you are using is going to see the drop in carrier that
 sending the string will cause. The communications applications will
 decide that you have gone off-line. Indeed, in order to avoid just such a
 situation in GHOST, when the modem port is switched back to your real
 port after a door is opened, GHOST sets the modem initialization string
 to null, and uses it's own internal strings whenever the modem needs to
 be initialized.

 When this string appeared on the remote screen, it was not too terribly
 difficult to determine that it came after GHOST had switched the current
 modem port to NONE.  The logic here is that if the string came before
 that, the modem port would still be the active one, and there would be a
 carrier drop, which GHOST would notice, and handle as if the user had
 logged off.  Ergo, the string had to be sent after GHOST had changed the
 comm port to NONE. This made me suspect that it had something to do with
 that switch, and the fact that the modem port was not changed from the
 real port, and still saw autoanswer as being on.

 If this ATS0=0 string appeared on my remote screen before the door had
 actually opened, i.e. while GHOST was dropping to DOS and running the BAT
 file to start the door, there was no problem. The door opened, and
 everything worked properly. However, there was absolutely no consistency
 when this string actually appeared at the remote end (i.e. was sent to
 the fax side of the modem on the host end). It might appear anywhere from
 1 second, to 10 or 12 seconds after the modem port was switched to NONE
 and  it was the latter that was the problem. If the ATS0=0 string was
 sent to the modem when the door had control of the comm port, it saw the
 dropped carrier, assumed the remote had lost it while in the door, and
 returned control to GHOST.

 I most certainly did not want to use a PAUSE of 10 or 12 seconds on the
 off chance that such a long pause was necessary, but I also did not want
 this problem to go on. The obvious solution was to find out where the
 ATS0=0 was coming from, change the PCP/Win set up to eliminate it, and
 then add the code to GHOST to modify that setting when GHOST was running.

 This turned out to be far more difficult than it looked. I checked
 everywhere in PCP/Win set up for such a string. I looked at PW2.INI, and
 even went so far as to look at my PW2.PRM file in a hex editor to see if
 I could locate where it was set.  Nothing!  Nowhere! Nada!

 While all this had been going on for me, I had been discussing my
 difficulties with Paul Heim on CompuServe.  Paul is a first class script
 writer, and a bulldog when it comes to problems. We discussed what was
 happening back and forth, and when I finally could not find anywhere that
 this was set up in PCP/Win, Paul asked me what FAXMON said.

 I hate to say this, but I couldn't answer, for the simple reason that I
 had totally forgotten that FAXMON.EXE was even in my \PROWIN2 directory,
 and that it could be used to monitor commands, etc. sent to the fax
 modem. Paul suggested that I run Faxmon in its Transaction Spy mode, and
 do nothing more than initialize the fax modem, but to be prepared for a
 surprise....

 I am afraid that Paul's warning was not strong enough... I wasn't just
 surprised... I was shocked! My fax init string in PCP/Win setup was a
 simple AT&K3^M,  that is, to turn on hardware flow control. Indeed, this is the string put there by PCP/Win when I installed the fax modem, and seemed to make sense. As a result, I expected to see that init string sent to the fax when I checked the report in FAXMON.

 Well, the init string was indeed there but, it was number seven out of a
 total of nine strings sent to the modem when the fax was initialized!
 Nowhere in PCP/Win setup did those other eight strings appear....

 Some time ago, when my eldest daughter was three or four years old, she
 used to like to drive. She would sit on my lap to she could see out the
 windshield, steer the car, shift the gears, and drive around town. Of
 course, we were parked at the time and the keys were not in the ignition
 but in my pocket.  The steering wheel moved a fraction of an inch because
 it was locked without the ignition on, and the gear shift required her to
 push a button to move it, -- a button positioned out of the reach of her
 tiny hands. She thought she was driving, but in reality, I had complete
 control of the car, and she had none.

 After running FAXMON, and initializing the fax modem, I began to feel
 like a three year old driving the car.  I had the illusion of control,
 but in reality, had none at all! Of course, the conclusion became
 inescapable.  If PCP/Win, unknown to me, was sending a total of nine init
 strings to the fax modem, was it not logical that PCP/Win might also be
 sending that silly and useless ATS0=0 string, without either my knowledge
 or any control of the string on my part?

 Sure enough, running FAXMON clearly showed the string ATS0=0 was being
 sent to the modem each and every time I switched the modem port from the
 real port to NONE.  It was not of my doing, and nowhere in PCP/Win could
 I configure things to stop it from doing this. I had already realized
 that PCP/Win would send the modem init string out when I switched the
 port back from NONE to the real port, and was able to prevent this by
 setting the modem init string to a null. But I could not do anything
 similar to stop the ATS0=0 from being sent.

 I was one frustrated script writer! That silly, and absolutely useless
 ATS0=0 string was preventing my script from functioning as it should, and
 I could do nothing to stop it from being sent.

 Or so I thought then.  Luckily, like Paul, I tend to be something of a
 bulldog.  When I calmed down, I began to wonder if that string was
 being sent because somehow, PCP/Win still saw the fax modem as being on
 the real comm port, and it had autoanswer turned on. Even though it was
 useless, PCP/Win was sending the autoanswer off Hayes command in that
 situation. Perhaps some code left behind from before PCP/Win handled
 autoanswer the way it does now was never removed because the developer
 didn't think it important or that it would hurt anything?

 In any case, it appeared fairly obvious that I had to turn off autoanswer so that the string would not be sent, and my doors would
 therefore, never see it. Obvious, but not that simple.....

 The logical place to do this, was immediately after GHOST had determined
 that a connection (data) was made, and a user was online. So, following
 that logic, I inserted a simple set autoanswer off command in that spot
 in the script.  Nothing happened. FAXMON did not show that autoanswer was
 disabled for the fax, and indeed, if I did a fetch on autoanswer after
 issuing the command, the result showed autoanswer still set to data and
 fax.  What now?

 There were at least two other places where this command would also work,
 or so I thought. I tried the same command in these places with exactly
 the same results - none!  Now, I really was getting confused. Why wasn't
 the set autoanswer off command working? What was going on??

 Test script time... first one, a simple one, like this...

 proc main
   set autoanswer datafax
   pause 5
   set autoanswer off
 endproc

 I compiled and ran the script and it seemed to work. When it started,
 FAXSTAT began running, and showed autoanswer enabled. When it stopped,
 FAXSTAT showed autoanswer disabled, and PCP/Win setup showed autoanswer
 set to Off. So that didn't help until I remembered what might be
 different when GHOST was running.  By the time GHOST knows that a user is
 online, and thus, can safely set autoanswer off, carrier is high on the
 modem.

 Time for another test script, this one a little more complicated, to
 test the command with carrier high.....

 proc main
   set autoanswer datafax
   pause 5
   transmit "AT&C0^M"
   if not waitfor "OK" 8
      statmsg "Carrier change not sent"
   endif
   pause 2
   if $carrier
      statmsg "Carrier high"
   else
      statmsg "Carrier low"
   endif
   pause 5
   set autoanswer off
   transmit "AT&C1^M"
   pause 5
 endproc

 Whoops!  Again, FAXSTAT began running as it should when the script began,
 and indeed showed that autoanswer was enabled. BUT! And this is a big
 one.  This time, when the script stopped running, FAXSTAT still showed
 autoanswer enabled, and so did PCP/Win setup! The set autoanswer off
 command had, as in GHOST, done nothing. PCP/Win had ignored it!

 Logic again.... obviously, set autoanswer has no effect when carrier
 is high. I tested all possible set autoanswer commands and none of them
 worked if carrier was high. Solution! I had to turn autoanswer off before
 carrier went high. Problem! In order to allow the use of Adaptive Answer,
 GHOST does not take over and do anything until such time as a CONNECT
 message is received, i.e. the call is a data call, and  by then, carrier
 is already high.

 I was stymied, but couldn't stop thinking about it. Then it hit me....
 when a user goes to open a DOS door, GHOST switches the port from the
 real port, to NONE. When it does so, THERE IS NO CARRIER ANY LONGER!

 Could I insert the command right after the port switch, and have it take
 effect before PCP/Win decided to send that silly ATS0=0 to the fax side?
 Since the earliest I had seen that ATS0=0 string appear was approximately
 one second AFTER the port switch, maybe, just maybe, it would work.

 And guess what ?  It did!! As soon as the data modem is switched to NONE,
 carrier drops, and the set autoanswer off command turns autoanswer off.
 And this happens before PCP/Win decides that it is going to send the
 ATS0=0 string to the fax side. That string is no longer seen on the
 remote end, and no longer interferes with door operations.

 What can we learn from this?

 1) Use every tool available to you when debugging a script. Don't just
 use the obvious, but look to tools that may not appear to have any use.
 One never knows. In my case, the forgotten FAXMON was the tool that
 eventually gave me the lead to the solution. Had Paul not mentioned it, I
 might still be struggling with the problem .

 2) Do not always assume that it is your coding that is causing a
 problem.  Review your code carefully, but if you still can't see anything that might be causing the problem, try looking elsewhere for a cause.  Don't trust any application. It may be doing something stupid and senseless like PCP/Win does by sending an ATS0=0 string to the modem. Just as startling is that string means absolutely nothing, since the S0 register isn't used under PCP/Win 2.xx.

 If your code looks solid to you, try looking elsewhere for the problem, using whatever tools you have available to track it down.

 3) Don't trust the Wasp manuals to tell you everything.  Nowhere in
 those manuals is there a mention that SET AUTOANSWER does not function if
 carrier is high on the modem port even though this is, indeed, the case.
 Do not expect that all SET commands will function as you want/expect them
 to, under all conditions.

 4) When you have a problem with your code not working as expected, don't
 always look for a problem that is logical or makes sense. PCP/Win sending
 a useless "ATS0=0" string to the modem is illogical, and makes no sense,
 but it was the cause of my problem. I suspect that, in most cases, if the
 cause of a problem was logical and/or made sense, it wouldn't be a
 problem. Don't forget to look for the stupid and illogical when hunting
 down a cause for a problem.

 5) DON'T GIVE UP EASILY! Some problems are easily solved. Others take
 time and effort, but can generally be solved, - just not as quickly. If
 you give up too easily, you may not find that solution, and may thus,
 abandon code that might be useful to yourself and others. Hang in
 there... it may be frustrating, and nerve wracking, but it also may pay
 off in the end.

 6) If you are having a problem that you can't seem to solve, ask others
 for their help. None of us knows everything there is a lot to know about
 Wasp, or, for that matter, anything else. If you can't find a solution,
 someone else may have run into a similar problem, and that experience
 could be useful to your situation. If nothing else, just talking about
 things can sometimes crystallize your own thoughts to the point where the
 solution becomes clearer, or even, obvious. Ask, and believe it or not,
 sometimes you just might receive! <GG>

 Enough for now.... I know we were going to continue discussing INI
 format files, and their uses, but this problem came up, and I wanted to
 discuss it here while it was still fresh in my mind. Next column, we'll
 go back to INI files.....

 Gregg Hommel is a much respected Aspect script writer and programmer. He
 is well known on the various nets hosting any number of conferences.
 Gregg sits on our Editorial Board. Comments concerning this or earlier
 tutorials can be directed to him as gregg.hommel@canrem.com

                                     ww



