CommTool.Exe  program documentation

The program name "CommTool" simply means "communication tool."  It is a serial port (most commonly, USB or RS-232) terminal program for Windows®, which runs in console mode.  It always requires the exclusive use of one (1) serial port.  Its purpose is to enable you to communicate with a single serial device through your computer, providing the text command-based interface to that device.  The serial device must be able to interact with the outside world using text commands.

Although CommTool is specifically tuned to work with any device using the MIRTOS Operating System, it can be used to communicate with nearly any serial device, such as a modem, a CNC router, or an ATmega microcontroller, for example.  In the case of a MIRTOS-based device, the basic functions are to interactively query and view its memory contents, to make program changes to it, to issue commands for it to execute, to obtain responses from it, to upload or download files in either batch or single-line mode, and to capture its serial output to disk.  CommTool is designed to be a serial-based device's user and computer interface.  It includes options to monitor and act upon specified strings it emits, and provides bidirectional access to the device from the Internet using email.


The user-configurable features of this terminal program will be explained below, many of which can be invoked from its command line.  A "/?" at any point on the command line is the help request parameter.  It causes the program to emit a terse help sequence and exit.  To reduce the need to remember and type multiple command line parameters each time, however, all configuration commands may be placed in and read from CommTool.Cfg, the default configuration file.  Alternately, a configuration may be read from a different file specified on the command line using the "/Cfg=" switch.  Some configuration options MUST be placed in a configuration file in order to utilize them, including all of those that require multiple text lines to define them, like scripts.  The "/NoCfg" switch tells CommTool not to read any configuration file.

This first simple CommTool command line example scans (using "/S") all available COM ports, from 1 through 100, and output a line for each one that it finds that it can successfully open:
  CommTool /S

Another version of the scan command limits the number of COM ports checked to 50 and generates dots for each ('x' at each ten) showing its progress, and the same text as above when one is found:
  CommTool /S50 /D

If a serial port is opened by another program and unavailable, it will not show up in the list of available ports.  Once the serial port is selected, a parameter selecting it can be added to the command line, as well as the communication rate.  The defaults are COM1 and 9,600 BPS (Bits Per Second.)  The following command line selects COM3 and initializes it at 57,600 BPS, for example:
  CommTool /B57600 /COM3

The basic command line parameters may be input in any order.  Some of the more complex parameters do have an order, but that will be explained further down.  If there are multiple parameters of the same type, the last one generally overrides a prior one.  For example, the following command would select COM3 at 80,000 BPS:
  CommTool /COM2 /B57600 /COM3 /B80000

If you noticed something odd in that last command, great; if not, please take a look at it again.  Hint: Have you ever used or experienced a communication rate of 80,000 BPS?  It certainly isn't one of the standard values!  This program was created in the early 1990s as a software solution to a hardware problem.  It began as a simple COM port terminal with an communication rate that could be fine-tuned.  Numerous serial devices had port clocking or other timing issues that caused their text output to be jumbled and text sent to them to either be rejected or (worse) misinterpreted by the device.  This program was the easiest way to remedy that recurring field communication problem - adjust the laptop's comm rate.  It retains that ability to utilize any serial communication rate supported by Windows®.  For example, 9580, 9590, 9620, 9638, 9700, 9844, etc. could be used when trying to synchronize communication with a serial device.  Notice that the values do not need to be a multiple of ten.  Since the value is used to calculate the PC's USART divisor, however, there may be no practical difference between close numeric values.

The "/A" parameter can be used to examine each BYTE received and sent at the BPS rate selected.  This can be especially helpful when identifying the placement of tabs, multiple spaces, a Carriage Return, or a Line Feed character.  It can also help to determine the correct communication rate since it shows how the computer's USART interpreted what it received.  This debugging format shows each block of BYTEs, often ten (10) at a time, as they are received, with both the hexdecimal representation on the left side and the ASCII equivalent (for displayable characters) or a simple '.' (for nonprintable ones) shown on the right side.  It is only anticipated that it will be used as a temporary debugging tool.

The "/D[####]" and "/E####" parameters change the bits in the Debug and EMailDebug bitmapped (or "flag") variables, respectively.  Using "/E" alone toggles local character echoing.  That feature is useful if the remote device does not echo back the characters sent to it.  Since most do, that feature is OFF unless explicitly enabled.  Use the "/?" command line switch to list other less frequently used command line startup options.

Press the Esc key to exit CommTool gracefully.  If for some reason it needs to be stopped immediately, the Control-C or Control-Break (or Task Manager) can be used, but those are certainly not the preferred method of ending program execution.  There is no exit logging, for example, when the program is forcefully terminated.


Function key macros

A key macro may be defined for each of the twelve (12) Function keys, F1 through F12, along with their Control-, Alt-, and Shift- modifiers.  Continuing with the previous command line example, this example command also instructs that a specific file be typed to the console when Control-F1 is pressed, another file be transmitted out the serial port when F2 is pressed, and that F8 toggle CommTool's capture to disk feature:
  CommTool /B57600 /COM3 "/CF1=Type CommTool.Log" "/F2=Send Filename.Hex" /F8=Capture

Note the double quotes that surrounded the first two complete function key assignment commands above, but are not present in the third one.  Double quotes are only necessary when a command's syntax has a space and a parameter, as is the case with both the Type and Send commands.  If a command requires a file name and CommTool can't open that file, it will reject the command and display a message.  When the file can be opened, however, CommTool stores the command and its name (but not the file itself) in memory, making the macro available to be invoked using the function keypress selected.  This means, for example, that an iHex file to be transmitted or a help file to be output to the console can be edited or replaced while CommTool remains running.  Action is then taken on whatever the contents of that file are at the moment that the command is invoked.

Each function key macro must be specified on a single line of text.  If more than one action is to be taken, use the Call keyword to call a script, which always spans multiple text lines.  A function key assignment begins by selecting which function key to attach to an action, followed by the action command.  To specify Alt-F1, for example, use AF1, or A-F1, or even Alt-F1.  Similarly, Shift-F2 can be specified just like that, or S-F2, or just SF2.  Finally, Control-F1, for example, can be specified that way or abbreviated as CF1, C-F1, or Ctrl-F1.  The keywords and syntax that may be used as function key action commands are:
  Call ScriptName - call the script specified by ScriptName, which can be nested
  Capture - toggle capture of both serial receive and serial transmit data streams to disk
  Dump Parameter - display specific information to the console; the Parameter can be any of these:
    Commands - display the HEAP buffer with the script command execution stack
    Email or ERx - display the HEAP buffer that has the Email strings checked and the action to be taken
    Events - display the Operating System's dwComEventMask value, with a description of any bit set
    Heap - display the main HEAP and seven (7) HEAP sub-block sizes and starting memory addresses
    LastLine or just Line - display the last line of text received from the serial port
    Key or Macro - display the HEAP buffer containing all function key macros defined
    POP3 - display the Post Office Protocol (i.e., email receive) HEAP buffer
    Scripts - display the HEAP buffer contining all of the scripts
    Serial or SRx - display the HEAP buffer containing the Serial strings checked and the actions to be taken
    TimedTask or Periodic - display the HEAP buffer that contains all the defined timed-based tasks
    WhiteList - display the HEAP buffer containing the only acceptable email command addresses
  Emit "character string",CR - emit the quoted character string to the serial port; CR is the optional carriage return
  PassThru or Pass - pass the function key's two (2) keycode BYTEs through to the serial port without modification
  Send Filename - open and sends the file out the serial port, either BYTE-by-BYTE or line-by-line (Esc to end transmission early)
  ProgCmd - allows a CommTool command to be input, like D? to display the debug mode value or D=0x1F to change it, for example
  Toggle - allows enable/disable or on/off toggling of one of these three (3) states:
    Capture - allows both serial receive and serial transmit data stream capture to disk to be toggled
    Timed - allows the timed scripts to be toggled
    Monitoring - allows the serial string monitoring to be toggled
  Type Filename - read the file and type it in the console, but not out the serial port
  WhiteList = User@Domain.Com - take action upon receiving an email command from this eddress

Here are just a few example function key macro configuration strings, as they could be included on the command line:  
  "F1=Type HelpFile.Txt"
  AF2=Capture
  "SF3 = Dump Macros"
  CF4=ProgCmd


One or more spaces either before and after the equal sign are ignored.  When there is a parameter following the command action word, at least one space is required, but multiple spaces are discarded.  Command words and action words are NOT case sensitive and generally may be abbreviated by using the fewest number of characters that uniquely identifies them.


Startup and configuration file

Consider this command line:
  CommTool /B57600 /COM3 "/F1=Dump heap allocation" "/CF1=Type HelpFile.Txt" "/F2=Send Filename.Hex" /F8=Capture ColorDump=0x1E

As you can see, the command line has quickly become long and complicated.  There are still many more features yet to be described below and utilized.  In order to be able to configure and tailor CommTool with all of the aspects that you commonly use, its parameters can be placed in and read from a configuration file.

When CommTool is first started, it searches for some specific items on the command line.  These are the "/Cfg=", "/Log=", "/NoCfg", "/NoLog", "/D" (debug mode), "/H" (total program HEAP space), "/Q" (quiet startup mode), "/S[###]" (scan), and "/?" or "?" commands.  If either "/?" or "?" is found anywhere on the command line, CommTool emits the help sequence and exits.  It then checks to see if the command line contained "/S", and if so, parses any numeric value found after the 'S' and scans COM ports COM1 through COM##, where ## is the number parsed.  COM99 is the default maximum if only "/S" is specified.

CommTool then checks for "/NoCfg".  If that string is not found on the command line, it checks for a "/Cfg=Filename" string and attempts to open and read the configuration from that file.  If that file doesn't exist, it does not attempt to open the default configuration file.  When neither "/NoCfg" nor "/Cfg=Filename" is found on the command line, it attempts to open and read the configuration from CommTool.Cfg, the default configuration file.  Finally, it rereads the command line, this time accepting all parameters it contains.  This means that a command line parameter overrides any placed in the configuration file.

The tiny configuration file below contains all of the optional parameters from the command line shown above, having moved all of them into the file.  Note that the double quotes required for command line commands with multiple parameters are not used in the configuration file, unless the parameter is a string.  They are needed on the command line due to the way parameters are conveyed from it into the program (i.e., to keep the command and its second parameter together, since each unquoted space is considered a field delimiter.)

B57600                      ; Note: Blocks like this one signify configuration file contents
COM3
F1 = Dump heap allocation
CF1= Type HelpFile.Txt ; This could contain function key reminders
F2 = Send Filename.Hex ; File to send to the MIRTOS device
F8 = Capture
ColorDump = 0x1E

All the configured features from the long command line are now activated by using this simplest CommTool invocation:
  CommTool

The configuration file can contain comments, as shown.  Comments are in the Assembly Language (rather than "C") style.  That is, any line that contains a ';' character is checked to see if it is a comment and if so, where the comment begins.  The active content of a line is truncated at first semicolon it finds, unless the semicolon is inside of a string.  A string is defined as a character(s) delimited by a double quote character on each end.  If a semicolon is found inside a string, it is retained, otherwise the line is terminated at that point.

The leading '/' character used for the command line switches many be omitted from the configuration file for readability.  Spaces around the equal sign work in the same way that was previously described.  The default file should be placed in the directory where CommTool is started.  If CommTool is configures with a shortcut, This can be specified by "Start In" in the Windows® properties popup.  If a different configuration file is specified, it is assumed to be in that same directory, but a fully pathed file name (e.g., C:\CTConfigs\PortCOM4.Cfg) is certainly valid.&nbps; This method would facilitate having a unique configuration file for multiple COM ports.  If the only thing that changes is the COM port used, a good solution is a single configuration file with the COM port specified on the command line.  No attempt to open a COM port is made until both the configuration file and the command line have been read (unless "/S[###]" was specified, of course.)

If a function key definition or other parameter is reused in a configuration file, each subsequent one replaces the prior one.  If a function key or other parameter is redefined on the command line, it replaces any prior one, even if the previous one was in a configuration file.  Consider this command line, used along with the configuration file shown above:
  CommTool /COM1 /B38400 /F1=Capture "/F2=Dump Macros" /COM4

CommTool would attempt to open COM4 at 38,400 BPS.  Both F1 and F8 would toggle capture to disk and F2 would display the HEAP block containing the Key Macros defined.  This method allows the configuration file to contain the program's default configuration but also allows a command line parameter to override some aspect of it.

CommTool requires the dedicated use of one (1) serial port per system console, but multiple instances, each with its own serial port, can be run in multiple consoles.  Each can read its configuration from the same file, or multiple configuration files can be used, with the command line specifying which serial port that instance is to use.  An example configuration file is shown near the end of this document.

If the first word on a line in a configuration file is "End", no further lines in the file will be read.  There can be spaces prior to "End" and almost anything after it, including spaces, a comment, or just the end of the line.  If the word is actually "EndIf", however, it does not mark the end of the configuration file, but indicates the end of a conditional script.

Capture streams to disk

The transmit data stream and receive data stream together can be captured to disk; they cannot be captured separately.  When MIRTOS starts, capture is disabled, but can be enabled and disabled using the function key macro already described.  Both streams are captured together, so the response to a command issued to a serial device is shown immediately following it.  Backspaces entered while editing a command are retained in the capture file.

Upon enabling serial port text capture to disk, the cursor is changed to a large block, and is changed back to normal size upon exiting capture.  The date stream capture filename format is in the YYYYMMDD_HHMMSS.Cap format, which means that it will be unique.  It also means that if capture is started, stopped, then started again, there will be multiple capture files.  CommTool makes no provision for concatenating capture files, although it's simple to do with the Operating System.  A capture file can be renamed upon ending the capture.  Serial data capturing is terminated either by using the Capture function key macro that enabled it, or upon exiting CommTool.


Scripts

Scripts are either named scripts, conditional scripts, or timed scripts.  Since timed scripts have a different command syntax, they are described after the named and conditional types.  Named routines or conditional routines begin with a user-defined, (hopefully) meaningful, unique, identifying string that contains no spaces and ends with the ':' character.  They contain one or more action commands and end with an exit keyword.  All scripts (including timed scripts) must be placed within a single block that begins with the word "Script" or "Scripts" then one of "Begin", "Begins", "Start", or "Starts" and ends with "Script Ends" or "Scripts End".  A few of the named scripts contained in the examples below are: IMAPLogon:, POP3Logon:, POP3Once:, SyncClock:, and UserAndPassword:.

The keywords and syntax that may be used as action commands are:
  Debug operator ValueString or Debug ? - modify the Debug variable using the operator (=, +=, -=, ^=, etc.) and value
  DebugE operator ValueString or DebugE ? - modify the Email Debug variable using the operator and parsed value
  DelayTime SecondsValue or Delay SecondsValue - number of seconds between POP3 or IMAP checks for new email while online
  Domain string - sets the domain string required for SMTP mail transmission; can be the computer name, for example
  Duration SecondsString - number of seconds to remain logged into POP3 server, checking for new email
  EDebug operator value - or EDebug ? - same usage as DebugE above; just a synonym for it
  EMailTx "string" or EMTx "string" or ETx "string" - string to send in the body of the email; may contain:
    $D - replaced in the string with the current date in the format [m]m/dd/yyyy, e.g., "2/15/2019"
    $D. - replaced in the string with the current date in the format Mmm., dd, yyyy, e.g., "Feb. 15, 2019"
    $D+ - replaced in the string with the current date in the format Month, dd, yyyy, e.g., "February 15, 2019"
    $T - replaced in the string with the current time in the format hh:mm:ss.m, e.g., "12:25:25.4"
    $W - replaced in the string with the current weekday string, e.g., "Friday"
    $W. - replaced in the string with the current abbreviated weekday string, e.g., "Fri."
  Flag ValueString - replace the value of the Flags word in the email structure being built
  From NameString - the name to place in the SMTP "From:" field (i.e., when sending email)
  GetCount Address [Address] [BYTE|WORD|LONG] - get and store information about emails
    Address - MIRTOS SRAM address where email message count (POP3) or EXISTS (IMAP) value is stored
    [Address] - MIRTOS SRAM address of optional second values: total BYTE count (POP3) or RECENT (IMAP) value
    Note: POP3 saves the number of email messages and (optional) total BYTE counts; IMAP stores the EXISTS and (optional) RECENT values.
    [BYTE|WORD|LONG] - optional storage length modifiers (1-BYTE, 2-BYTEs, or 4-BYTEs); applies to both parameters
    Note: The default storage length is WORD for all four values except the POP3 total BYTE count, which is stored as a LONG by default.
  Host - the POP3, SMTP, or IMAP server to which the new connection is to be attempted
  Label string - specifies a identifying name for a new email structure
  Login SelectString or Logon SelectString - begin executing the SelectString (POP3, SMTP, or IMAP) mail routine
  Logoff IMAP [Label] or Logout IMAP [Label] - log out of all IMAP servers or a specific labelled server
  Log "string" - string to be written to the log file
  NOp - perform no operation; may be used as a placeholder
  PassWord string - the email account password string, containing no spaces
  Push Debug or Push EmailDebug - save the current value of the specified debug variable on a special 32-value stack
  Pop Debug or Pop EmailDebug - restore the most recently value PUSHed of the specified variable from its stack
  PollTime value or Poll value - same usage as Duration above; just a synonym for it
  Port value - override the default IP PORT in the email configuration; defaults: SMTP = 25, POP3 = 110, and IMAP = 143
  Print string - string to emit out the console, but not out the serial port
  ProgCmd "string" send the string to the CommTool command line processor to change some parameter while running
  ProgCmd - accept keyboard input for a new or replacement single-line command
  Recipient string or SendTo string or To string - destination eddress
  SendTo Eddress or ToName Eddress - the email address to which the message is to be sent
  SerialTx "string" or SerTx "string" or STx "string" - string to send out the serial port; may contain:
    $RTC[#] - output the computer's clock to the MIRTOS device, in a specific format (see the example)
  SMTPTx "string" - same as EMailTx above; just a synonym for it
  Subject "string" - short text to place in the email Subject line; may contain special characters shown in EMailTx above
  Type "string" - open and send a file to the console only; don't transmit it

Conditional scripts

The keywords and syntax that invoke a conditional script are:
  If SRx "string" - begin executing the script if serial port text contains the specified string
  If ERx "string" - begin executing the script if a received email contains the specified string

Do not place a conditional script within another script.  The terminating keywords for these script types are shown below.  It was decided to not to be pedantic by requiring that a Call always end with a "Return" or that an "If" always be terminated with an "EndIf", for example.  That may change if CommTool is revised (for example, if a conditional script were to be allowed within another script), so it is a good idea to use the appropriate keyword.
  EndIf - preferred conditional script terminating keyword
  Return - preferred script terminating keyword for all other scripts
  Exit - accepted script terminating keyword

Timed tasks

Another script category is the timed script.  It differs from the other two in that it is invoked with a single line, containing precisely two (2) parameters, and has no "EndIf", "Exit", or "Return" terminating string. Its syntax is simply:
  Timed Interval ScriptName - maintain a timer and call the named script every time the interval seconds passes

Script command words are NOT case sensitive.  Scripts may be invoked by function key commands, on the occurrences of a specific events, or by other scripts.  When one scripts call other script, the next instruction (that is, the one after the CALL) in the calling script is saved on a script stack.  Upon return from the called script, execution resumes at that next instruction.  The script stack has a limit of 128 saved return addresses.  In practice, no more than about ten (10) ever seem to be needed.  Separate memory areas are maintained for the script CALL stack, the Debug variable stack, and the Email debug variable stack.  If a script encounters an invalid keyword during processing, it will output a message to the console and skip the command, but continue with the rest of the script.

Many of the scripts deal with email; here are a couple examples of others before getting to those:
Scripts Begin
SetFavoriteDebugMode:
ProgCmd "D=32"
ProgCmd "E=1"
ProgCmd "D?"
ProgCmd "E?"
Return

SyncClock: ; Script to synchronize a MIRTOS device's clock with the computer's clock
; SerTx $RTC1 ; Only send the seconds value
; SerTx $RTC2 ; Only send the second and minute values
; SerTx $RTC3 ; Send second, minute and hour values
; SerTx $RTC4 ; To the three (3) above, add the day of the week
; SerTx $RTC5 ; Send second, minute, hour, weekday and date
SerTx $RTC6 ; Send all five (5) above plus month; only omit the year
; SerTx $RTC7 ; Send all seven (7) values: seconds through year
Return ; Be sure to uncomment the one above to be used

Timed 3600 SyncClock ; Synchronize the MIRTOS device's clock once each hour
Scripts End

Blank lines, indentation, and comments are all optional.  They are supported for script readability and to convey or explain the purpose of the script command or sequence or commands.  In the example above, only the single command SerTx $RTC6 is retained and stored in the script HEAP block.


Serial string monitoring

CommTool can be configured to monitor the stream of BYTEs coming from the serial port and take some action(s) when one of the defined strings is received. One of those actions is to create and send an email message.  These are part of the conditional scripts, which are simply scripts that begin with "IF".  They have one or more action commands in them and again, end in "EndIf", "Exit", or "Return".  Many strings may be defined.  Defined strings are only checked, any action taken, and the monitor buffer cleared upon encountering the Carriage Return (= 0x0D) character.

Here are two examples of how serial string monitoring may be configured:
Scripts Begin
IF SerRx "DI3 On"
CALL SendDI3Command
ENDIF
If SRx "DI4 On"
Call SMTPSetup
ETx "Bedroom door opened at $T on $W., $D"
LogOn SMTP ; Send the email
Call IMAPLogon ; Make sure that a response can be received
EndIf
Scripts End

The scripts in the example above are incomplete since they don't show the SendDI3Command, SMTPSetup, or IMAPLogon scripts which they call.  Those are listed in the example configuration, near the end of this page.  The example above should be sufficiently descriptive, however, to provide both the idea of what can be done and how easily it can be accomplished and tailored.

The CommTool string monitoring scripts can easily be tested with MIRTOS-based devices without generating the actual condition that outputs the monitored string.  Since CommTool is monitoring the data stream, watching for specific character sequences, simply type a semicolon then send the string to be tested to the device.  The semicolon also marks the beginning of a comment in MIRTOS device.  If the device is echoing characters (which it is, by default), then that string will be echoed back and the conditional script invoked.  If a typing mistake is made, however, while entering the monitored string into the MIRTOS device's editing buffer, and a backspace is entered to revise it, the string will not be an exact match for the monitored string.  If a complete monitored string is received, but enough backspaces are entered afterward to appear to clear the editing buffer before a Carriage Return is encountered, the string will still match.

Using EMail

CommTool can also send and receive email.  This allows it to check for specific text from the email it retrieves, much like it does for the serial data stream.  It can also retrieve email and send commands to the serial device based on the content of that email.  These two features gives the serial device access to the web.  This facilitates information being sent to and received from your cell phone, or tablet, for example, even when you're away from the device to which CommTool is connected.

When email is configured and used, each of the three (IMAP, POP3, and SMTP) email protocol servicing tasks used is run as a state machine in its own separate completion thread.  The POP3 and IMAP protocols are used for retrieving email while SMTP is used to send it.  Not all of them need to be utilized.  A POP3 thread can make one query of the email server and exit, or it can poll at a specified interval for a specified duration, then exit.  An IMAP thread will continue to run until explicitly instructed to "LogOff".  An SMTP thread only sends an email and exits, so it does not remain active for very long.  If emails are sent to multiple recipients, each will have its own completion thread.

A WhiteList of accepted email sources may be defined.  If none are defined, email is accepted from any eddress.  When at least one WhiteList entry are defined, all received emails are checked to see if they came from one of the preapproved eddresses.  Both the email retrieval routines (IMAP and POP3) check the Whitelist entries.  Note that neither uses TLS or SSL.  The POP3 client deletes each email after processing it; the IMAP client moves each into another subdirectory on the email server after processing it.  This is an email script example when using the POP3 protocol:
F12 = Call POP3Once
AF12=Call POP3Poll30

WhiteList=AcceptFrom_1@YourEmailHost.Com
WhiteList = AcceptFrom_2@YourEmailHost.Com

Scripts Begin
IF ERx "ALARM+"
SerTx "O* = 63" ; Enable the alarm horn output
EndIf
IF ERx ALARM-
SerTx "O* = 0" ; Silence the alarm horn
EndIf

POP3Once:
CALL POP3Setup
; FLAGs |= 32 ; FLAG_SKIP_BODY
LOGON POP3
RETURN
POP3Poll30:
CALL POP3Setup
DelayTime 3 ; Seconds delay between requests for new mail
PollTime 30 ; Second to remain looping in the DelayTime interval
LOGON POP3
RETURN
POP3Setup:
Print Executing the POP3 setup script.
Label POP3Setup
HOST POP.YourEmailHost.Com
CALL UserAndPW
RETURN
;---------
UserAndPW:
; Print Executing the UserAndPW script ; (commented out)
User User@YourEmailHost.Com
Password SecretPassword!
Return
Scripts End

An IMAP client differs from a POP3 client in CommTool in that once it begins, the IMAP client only exits when it is commanded to stop (or the connection to its server is broken), not after a timed period.  The same DelayTime SecondsValue keyword that POP3 uses is used by IMAP to configure how long to wait between checks for any new email arrival. : Here is an IMAP initialization example:
SF12 = Call IMAPLogon     ; Shift-F12
CF12 = Call IMAPLogoff ; Control-F12

Scripts Begin
IMAPLogon:
HOST IMAP.YourEmailHost.Com
DelayTime 5 ; Seconds delay between requests for new mail
CALL UserAndPW ; Uses the same script defined above
LOGIN IMAP
RETURN
IMAPLogoff: ; Log out of all open IMAP servers
Print Executing IMAP logoff.
LOGOFF IMAP
RETURN
Scripts End

The first conditional script presented above referred to SendDI3Command, SMTPSetup, and IMAPLogon routines.  An example of the last one is shown above; an example of each of the other two (2) is contained in the example below.  There is no function key assigned to invoke an SMTP script since it is started based on a sensed condition.

Scripts Begin
SendDI3Command:
CALL SMTPSetup ; Prepare to send the string below
Subject "DI3 contact closed at $t on $d"
ETx "Motion sensed at $T on $W., $D"
Logon SMTP
CALL IMAPLogon ; Logon to listen for any reply
RETURN

SMTPSetup:
Print Starting the SMTPSetup script
Label SMTPSetup
HOST SMTP.YourEmailHost.Com
DOMAIN MyComputerName
CALL UserAndPW ; Uses the same script already defined
; SendTo VerizonCell@VText.Com
SendTo EmailAccount@SomeOtherEmailHost.Com
FromName HomeSCADA monitor
ToName My cell phone
RETURN
Scripts End

The email FLAGS word is a bitmapped variable which allows certain actions to be changed from their defaults while processing received email.  They may be combined.  All are valid when using the POP3 protocol; IMAP uses only FLAG_ALL_MATCHES.  The meaning of each of the ten (10) FLAG_ BITs used are:
   0x00011FLAG_JUST_COUNTS - exit after STAT command (i.e., just get the message count and BYTE count)
0x00022FLAG_CAPABILITIES - send the CAPA request upon successfully logging in
0x00044FLAG_SEND_UIDL - request that each message's unique ID be sent
0x00088FLAG_SEND_TOP - include the TOP command to request the first 20 lines of text
0x001016FLAG_SKIP_SUBJECT - do not check the subject line in the email message; just check the message body
0x002032FLAG_SKIP_BODY - do not check the body of the email message; just check the subject line (default: check both)
0x004064FLAG_SKIP_DELETE - do not delete the message after reading and processing it
0x0080128FLAG_ALL_MATCHES - do not stop after the first match; continue checking the message (POP3 and IMAP)
0x0100256FLAG_ADDR1_HEX - display the message count address in hex format instead of decimal when FLAG_JUST_COUNTS is 1
  0x0200    512   FLAG_ADDR2_HEX - display the total BYTE count address in hex format instead of decimal when FLAG_JUST_COUNTS is 1

Pressing the Esc key to exit CommTool normally will send an exit command to each active email completion thread so it can perform an orderly shutdown.  There will likely be a small, but noticeable, delay if any email client is active and needs to finish and shutdown.


Changing and using the text color

The color of the text output to the console when CommTool is in some specific states can be changed.  By default, CommTool will output all text in the console color that is active when the program began.  Different text colors are useful to identify the text's information source.  None, or one, or all may be active at the same time.  If only one is active, for example, all text except that condition will output text in the same color.  The text color feature is most helpful when a lot of output is being generated, or during debugging, in determining the source of some specific text or highlighting something of interest.  Note that the text color changes are not included in text captured to disk, however.  The alphabetized list of color keywords and when they are activated:
  ColorCommand or ColorCmd - when entering a new ProgCmd parameter
  ColorDefault or ColorText - when the default program text color was changed from the one in effect when the program began
  ColorDump - when the output is coming from one of the Key Macro HEAP Dump commands
  ColorInfo - when file capture starts/stops, a timed or serial script begins, an email structure is loaded, or a formatted string is created
  ColorIMAP - when output is generated by the IMAP scheduler or IMAP state machine completion task
  ColorIMAPGRC - when there is a change in the IMAP reply count (GRC means Get Reply Count); enabled by GRC flag
  ColorIMAPTxRx - when the email Details flag is set and any IMAP packet is sent or received
  ColorIMAPTxRxFail - when an IMAP SOCKET request, or its reply, fails
  ColorPOP3 - when output is generated by the POP3 scheduler or POP3 state machine completion task
  ColorPrint or ColorScriptPrint - when text is being output by a script print action word
  ColorSMTP - when output is generated by the SMTP scheduler or SMTP state machine completion task
  ColorSock - when in the Winsock initialization, host lookup, connection, transaction, close, error, or termination logic
  ColorScriptCmd - when output is from an ProgCmd action word or serial port output is from a script

CommTool uses the same color number values that the Windows® Color command uses.  The "Color /?" system command can also be utilized to obtain the same set of values as shown below, although the system command does not use the leading "0x" prefix, since it assumes that its attribute parameter is always a hexadecimal value:
  0 = Black, 1 = Blue, 2 = Green, 3 = Aqua, 4 = Red, 5 = Purple, 6 = Brown, 7 = White, 8 = Grey,
  9 = Bright Blue, A = Bright Green, B = Teal, C = Bright Red, D = Magenta, E = Yellow, F = Bright White


Each color code is a 2-digit hexadecimal value, so be sure to use the "0x" prefix (or its decimal equivalent) to obtain the desired results.  The first hex digit specifies the background color; the second selects the foreground color.  A single hex digit can be used, in which case the background color will be black.  Here are a few examples:
  ColorText=0xA - Bright green text on a black background   (same as ColorText=10, for example)
  ColorText=0x8F - Bright white text on a grey background
  ColorText=0x1E - Yellow text on a dark blue background

Debugging features

There are several debugging features in CommTool which are initially disabled.  Two bitmapped variables, Debug and EDebug, may be set from the command line using "/D[####]" and "/E####", respectively.  If only "/D" is specified, Debug is set to 1.  If only "/E" is specified, EDebug is unchanged, but character echoing is toggled.  To change the EDebug value, specify a numeric value.  Either may be saved using Push and restored using Pop within a script.  They can also be modified by the script to enable or disable specific debug output during script execution.  Saved values are not automatically restored, so if a Push is used, verify that the corresponding Pop is also present.

The first three (3) bits in the EMailDebug table select whether any IMAP, POP3, and SMTP debugging is enabled.  Since enabling the debug output for all of a prococol's states produces so much output, the ability to selectively enable and disable specific states for each one was obviously needed.  The keyword names and syntax for the three (3) protocol state machine filters:
  DebugIMAPFilter=NumericString - select which debug states in the IMAP (email retrieval) state machine are enabled
  DebugPOP3Filter=NumericString - select which debug states in the POP3 (email retrieval) state machine are enabled
  DebugSMTPFilter=NumericString - select which debug states in the SMTP (email sending) state machine are enabled

The IMAP states (each displayed as "IMAP_ItemName" below) in CommTool are:
0INITIALIZENew email structure check and initialize the HEAP-based memory block
1CREATESOCKETCreate a new socket for the TCP/IP connection
2CONNECTResolve the host IP address and connect to it
3LOGINLog into the IMAP server with username and password
4LISTFOLDERSDetermine which folders already exist and which need to be created
5MD_ACCEPTEDCreate the Accepted folder if it didn't already exist
6MD_ACTEDUPONCreate the ActedUpon folder if it didn't already exist
7MD_TOOLARGECreate the TooLarge folder if it didn't already exist
8MD_FROMINVALID  Create the FromInvalid folder if it didn't already exist
9MD_MISCREJECTCreate the MiscReject folder if it didn't already exist
Loop begins
10SELECTINBOXSend a Select query; get total and recent counts; if there is no new (i.e., "recent") emails, select WAIT as the next state
11FETCHFASTRequest the date, time, and email size in BYTEs; select TOOLARGE as the next state if the email is too large*
12GETFROMRequest the sender's eddress; select the next state of MISCREJECT if no "From" found, of GETBODY if the sender matched a whitelist entry or there are no Whitelist entries, or of FROMINVALID if there was no match to any Whitelist entry
13TOOLARGERequest that the email be moved to the TooLarge folder; set the next state to SELECTINBOX if successful, LOGOUT if not
14FROMINVALIDRequest the the email be moved to the FromInvalid folder; set the next state to SELECTINBOX if successful, LOGOUT if not
15MISCREJECTRequest that the email be moved to the MiscReject folder; set the next state to SELECTINBOX if successful, LOGOUT if not
16GETBODYRetrieve that the email body; check the subject and message body for one of the ERx strings specified; if a match is found, queue the action specified and select ACTED_UPON as the next state, otherwise set it to ACCEPTED
17ACCEPTEDRequest that the email be moved to the Accepted folder; set the next state to SELECTINBOX if successful, LOGOUT if not
18ACTEDUPONRequest that email be moved to the ActedUpon folder; set the next state to SELECTINBOX if successful, LOGOUT if not
19WAITWait for the DelayTime to pass then set SELECTINBOX as the next state
Loop ends
20LOGOUTLog out of the IMAP server
21CLOSESOCKETClose the TCP/IP socket used
22FREEHEAPFree the HEAP-based memory used
  23  EXITWait in this state for the thread logic to close the thread

* The default IMAP buffer size is 10,240 BYTEs.  It can be changed using the "/A" command line switch.  Its minimum accepted value is 5,120 BYTEs.

The defaults are that no debugging output of any email retrieval or transmission state is enabled.  The output for the IMAP, POP3, or SMTP state machines can enabled or disabled by setting and clearing the matching bit in the Email debug variable.  When enabled for a specific protocol, the Debug####Filter keyword is checked.  If one was not initialized for that protocol, then all of its states are enabled.  For the DebugIMAPFilter, for example, the suggested value of B11100001-00010000-00000111 selects only the IMAP_INITIALIZE (0), IMAP_CREATESOCKET (1), IMAP_CONNECT (2), IMAP_GETFROM (12), IMAP_GETBODY (16), IMAP_LOGOUT (21), IMAP_CLOSESOCKET (22), and IMAP_FREEHEAP (23) states to generate their debug output.  BIT 0 is the rightmost, and BIT 23 the leftmost in this example.


Other miscellaneous commands

CommTool can be configured to pass any extended (i.e., 2-BYTE) keypress out the serial port.  If an action for extended key (including a function key) is not defined, the keypress is simply discarded.  To determine the keycode for a specific key, use the "/D=0x200" command line debugging option.  Some keys that are used interchangeably actually have more than one key code, for example:
Pass=0,71     ; Home in the numeric keypad
Pass=224,71 ; Home in the cursor movement key block
Pass=0,75 ; Left in the numeric keypad
Pass=224,75 ; Left in the cursor movement key block

When any Serial Monitoring script is defined, serial monitoring is initially enabled by default.  The same is true for Timed scripts.  It may be desirable to initially disable one (or both) of them or be able to toggle either of them on and off.  The configuration file commands shown below show how to utilize this feature:
Off:Timed          ; or "Off=Timed" (equal or colon accepted)
Off:Serial ; either "Serial" or "Monitor" is accepted
AF10 = Toggle Timed
SF10 = Toggle Serial monitoring ; Actually, "Togg Ser" would be enough

Program log file

When the CommTool program starts, stops, or when some other specific events occur, the time and date stamped event is logged to disk.  Logging can be globally disabled using the "/NoLog" command line switch.  The default log file name is CommTool.LOG, but can be overridden using "/Log=Filename" on the command line.  The script command LOG "string" will cause that quoted string to be written to the log file, unless logging is globally disabled.  Unless disabled with some /L## numeric value option, the each program event category listed below creates a LOG file entry.  These event flags, which are all initially ON, are:
   0x00011StartStop - create a log entry when the CommTool program starts and when it stops
0x00022ConfigError - log any configuration command that CommTool could not interpret and consequently rejects
0x00044FileError - log whenever there is an error in opening an existing file or in creating a new file
0x00088LastError - log the message that the DisplayLastError routine displays whenever it is called
0x001016WSAError - log the message that the DisplayLastWSAError routine displays whenever it is called
0x002032IMAP - log when preparing to schedule a new IMAP completion thread
0x004064POP3 - log when preparing to schedule a new POP3 completion thread
  0x0080    128   SMTP - log when preparing to schedule a new SMTP completion thread


Configuration file example

Here is an example, starting configuration file that combines the examples above together, and adds quite a few more:
A=12000 ; POP3 buffer (HEAP) memory allocation size
B=57600 ; Baud (bits per second) serial data communication rate
COM3 ; Serial port to use

; Text color keyword & value Background Foreground
ColorCommand = 0x47 ; Orange White
ColorIMAP = 0x9F ; Blue White
ColorPOP3 = 0x09 ; Black Bright Blue
ColorSMTP = 0x0B ; Black Bright Cyan
ColorScriptPrint = 0x71 ; White Blue
ColorScriptCmd = 0x7A ; White Bright Green
ColorDump = 0x1E ; Blue Yellow
ColorScriptDebug = 0x0C ; Black Bright Red
ColorIMAPCapa = 0x0A ; Black Bright Green
ColorIMAPTxRx = 0x27 ; Green White
ColorIMAPTxRxFail = 0x37 ; Teal White
ColorIMAPGRC = 0x57 ; Magenta White
ColorInfo = 0x8F ; Grey White

F1 =Emit "?",CR ; Causes MIRTOS' embedded help sequence to be output
AF1=Dump POP buffer
CF1=Type HelpFile.Txt
SF1=Dump LastLine buffer
F2 =Dump Heap ; Display the HEAP memory allocation data, but not HEAP contents
AF2=Dump key macros
CF2=Dump ERx strings
SF2=Dump SRx strings
F3 =PassThru ; or simply "Pass"
AF3=Dump Scripts
CF3=Dump COM status
SF3=Dump Commands
F4 =Pass
F5 =Dump Timed tasks
CF5=Dump WhiteList
SF5=Dump EMail structures
F6 =Emit "E 1 ^= 0x40",CR ; Toggles the MIRTOS device's sequencer logic
SF6=CALL IMAPLogon
F8 =Capture

F10 = ProgCmd
AF10 = Toggle Timed
CF10 = CALL SetFavoriteDebugMode
F11 = CALL SyncClock
SF12 = Call IMAPLogon
CF12 = Call IMAPLogoff

Off = Timed scripts

; These are commented out:
; Pass=0,71 ; Home in the numeric keypad
; Pass=224,71 ; Home in the cursor movement key block
; Pass=0,75 ; Left in the numeric keypad
; Pass=224,75 ; Left in the cursor movement key block

DebugIMAPFilter=B11110001-00010000-00000111
DebugPOP3Filter=0x1F300F ; Valid states: 0 through 20
DebugSMTPFilter=0x3F8F ; Valid states: 0 through 14

;---------- SCRIPTS ----------
Scripts Begin

Timed 3600 SyncClock ; Synchronize the MIRTOS device's clock once each hour

IF SerRx "DI3 On"
CALL SendDI3Command
ENDIF
If SRx "DI4 On"
Call SMTPSetup
ETx "Bedroom door opened at $T on $W., $D"
;Note: "$T on $W., $D" --> "12:26:25.0 on Fri., 4/26/2017"
;Note: "$T on $W, $D+" --> "12:26:25.2 on Friday, April 26, 2019"
;Note: "$T on $W. $D." --> "12:26:25.4 on Fri., Apr. 26, 2019"
LogOn SMTP ; Send the email
Call IMAPLogon ; Make sure that a response can be received
EndIf

IF ERx "ALARM+"
SerTx "O* = 63" ; Enable the alarm horn output
EndIf
IF ERx ALARM-
SerTx "O* = 0" ; Silence the alarm horn
EndIf

IMAPLogon:
HOST IMAP.YourEmailHost.Com
DelayTime 5 ; Seconds delay between requests for new mail
CALL UserAndPW ; Uses the same script defined above
LOGIN IMAP
RETURN
IMAPLogoff: ; Log out of all open IMAP servers
Print Executing IMAP logoff.
LOGOFF IMAP
Return

POP3Once:
CALL POP3Setup
; FLAGs |= 32 ; FLAG_SKIP_BODY
LOGON POP3
RETURN
POP3Poll30:
CALL POP3Setup
DelayTime 3 ; Seconds delay between requests for new mail
PollTime 30 ; Second to remain looping in the DelayTime interval
LOGON POP3
RETURN
POP3Setup:
Print Executing the POP3 setup script.
Label POP3Setup
HOST POP.YourEmailHost.Com
CALL UserAndPW
RETURN

SetFavoriteDebugMode:
ProgCmd "D=32"
ProgCmd "E=1"
ProgCmd "D?"
ProgCmd "E?"
Return

SyncClock: ; Script to synchronize a MIRTOS device's clock with the computer's clock
; SerTx $RTC1 ; Only send the seconds value
; SerTx $RTC2 ; Only send the second and minute values
; SerTx $RTC3 ; Send second, minute and hour values
; SerTx $RTC4 ; To the three (3) above, add the day of the week
; SerTx $RTC5 ; Send second, minute, hour, weekday and date
SerTx $RTC6 ; Send all five (5) above plus month; only omit the year
; SerTx $RTC7 ; Send all seven (7) values: seconds through year
Return ; Be sure to uncomment the one above to be used

SendDI3Command:
CALL SMTPSetup ; Prepare to send the string below
Subject "DI3 contact closed at $t on $d"
ETx "Motion sensed at $T on $W., $D"
Logon SMTP
CALL IMAPLogon ; Logon to listen for any reply
RETURN

SMTPSetup:
Print Starting the SMTPSetup script
Label SMTPSetup
HOST SMTP.YourEmailHost.Com
DOMAIN MyComputerName
CALL UserAndPW ; Uses the same script already defined
; SendTo VerizonCell@VText.Com
SendTo EmailAccount@SomeOtherEmailHost.Com
FromName HomeSCADA monitor
ToName My cell phone
RETURN

; Consider keeping the script which set the username and password as the final one.
UserAndPW:
; Print Executing the UserAndPW script ; (commented out)
User User@YourEmailHost.Com
Password SecretPassword!
Return
Scripts End

END When a line begins with "END" (but not "ENDIF"), the program stops reading the file there.

Program debug constants, changed using "D=0x184" (or "|=", "^=", etc.), for example:
0x0001 1 Displays COM port & structure information during startup
0x0002 2 Displays the memory address instead of buffer offset during dumps
0x0004 4 Removes blocks of repeating zeros from memory dump output
0x0008 8 Displays detailed status when sending a file out the serial port
0x0010 16 Outputs when serial last line check matches a saved string
0x0020 32 Shows details of information stored by the Key Macro save logic
0x0040 64 Dumps the Key Macro buffer in that same Key Macro save logic
(Suggest using with flag 0x0004 to reduce the output)
0x0080 128 Displays details during script execution
0x0100 256 Shows where (routine name) an ESC keypress was processed
0x0200 512 Shows the single or extended (i.e., "2-BYTE") keycode for each key pressed
0x0400 1024 Shows details when an email completion thread starts or stops
0x0800 2048 Shows details when a timed task begins execution

EMail debug constants, changed using "E=0x40", for example:
0x0001 1 Shows process information in the IMAP state machine completion thread
0x0002 2 Shows process information in the POP3 state machine completion thread
0x0004 4 Shows process information in the SMTP state machine completion thread
0x0008 8 Shows socket connection attempts and results for the IMAP, POP3, and SMTP protocols
0x0010 16 Shows some additional details in many of the IMAP, POP3, and SMTP states
0x0020 32 Shows some details when the IMAP scheduler starts a new IMAP completion thread
0x0040 64 Shows information generated by the IMAP GetReplyCount logic
0x0080 128 Shows a time and date formatted email string from an EMailTx action string
0x0100 256 Shows the details when a POP3 or IMAP ERx string is matched
0x0200 512 Causes the email string matching routine to leave received email HTML codes intact

Notes

CommTool was originally written as a 16-bit application, named PortMon.  It was converted to a 32-bit application in 1997, and has been actively maintained as a 32-bit application since then.  This was done intentionally and means that it should run correctly on any version of Windows® from NT and XP, all the way up through Windows® 10, in either the 32-bit or 64-bit platform.  There may still be a use for that older computer!

The numeric value parsing routine in CommTool can handle strings representing decimal, hexadecimal, or binary values.  A hexadecimal string must begin with "0x" or "0X", followed by only these characters: 0 1 2 3 4 5 6 7 8 9 A B C D E F a b c d e f; any other character (commonly, a space) exits the parsing function, returning the value parsed up to that point.  A binary string must begin with 'B' or 'b' and contain only these characters: 0 1 -.  The dash is a spacer, used like a comma in decimal values to visually break up a long string of binary digits.  For example, B11110111-00110001 is a binary string, equal to 0xF731 hexadecimal and 63,281 decimal.

The /M (for Mode) command line parameter selects BYTE-by-BYTE file transmission mode instead of the default line-by-line mode for the Send function key command.  Use the Esc key to end file transmission before the end of the file, when transmitting a file.  Although this is the same key used to gracefully exit the CommTool program, Esc is treated differently during file transmission.  A second Esc keypress is then required to exit the program.

CommTool.Exe can be renamed, in which case, by default, it will look for its configuration file with its new name, but with .Exe replaced with the .Cfg extension.  Explicitly specifying a configuration file name by using "/CFG = Filename", or specifying "/NoCfg" as a command line parameter overrides the default.

Downloads page