hsms, secsport Tcl Commands


hsms, secsport - Tcl commands for SECS communication


::dmh::secsport portname ?tty_device? ?baudrate?
::dmh::secsport portname terminalServerPort
::dmh::hsms portname passive socketNum
::dmh::hsms portname active socketNum ?hostnameOrIP?
portname abort SsFf ?callback?
portname close
portname lastheader
portname online
portname ppbody_put S7Ff?R? PPID bodyType bodySize pathName ?callback? ?-whenreply tcl_code?
portname put SsFf?R? ?TSN? ?callback? ?-whenreply tcl_code?
portname put linktest ?callback?
portname putl SsFf?R? ?codes? ?callback? ?-whenreply tcl_code?
portname reset
portname tracewin
portname whenever SsFf ?tcl_code?
portname whenmsg SsFf ?tcl_code?
portname whenmsg again

Configuration Options


This manpage describes the secsport and hsms commands which are used for Semiconductor Equipment Communication Standard (SECS) protocol communication from within a Tcl/Tk application.  See the GEM Equipment Interface Applications document for information on the configurable Tcl/Tk host and equipment applications that use these commands.

The secsport command is used for SECS-I and SECS-II communication using RS-232 ports. There are three varieties of RS-232 ports supported by the secsport command. First, there are the usual /dev/tty or COM ports supported directly by your operating system. Second, the secsport command supports RS-232 ports where the hardware or terminal server vendor has provided software drivers that make the ports appear to be supported by the operating system. An example would be using a Xyplex terminal server and their csportd driver software. Third, the secsport command can establish a TCP/IP connection and exchange the same SECS-I/SECS-II data streams that are usually exchanged with an RS-232 port. This option is typically used to directly communicate with a terminal server over a local area network. The terminal server relays the data streams through its RS-232 port.

The hsms command is used for SECS-II communication using HSMS-SS TCP/IP connections. Both the 1993 draft standard and the 1995 SEMI standard are supported.

Multiple ports of any connection type can be used simultaneously from a single Tcl program. Each port connection needs to be configured with its own serial SECS-I port, or its own TCP/IP socket number.

A port connection is created using the secsport or the hsms command; for example

set spname [secsport mach1 /dev/ttya 9600]
puts "secsport $spname has been created"

The port connection is given a name when it is first created. The name, mach1, in this example, becomes both a Tcl command, and the name of a global data array.

When first created, the port connection does not respond to the port hardware or connection attempts. You use the online command to begin communication. Before using the online subcommand, specify how received messages are to be handled. Also, you may want to change some of the port settings from their default values. For example:

global mach1
set mach1(DEVID)  3
set mach1(EQUIP)  0
set mach1(TRACE)  0x440e
mach1 whenmsg S1F1 { mach1 put S1F2 L ; mach1 whenmsg again }
mach1 tracewin
# Now begin communications
mach1 online

Most of the time during development, you will want to have a window that displays communication activity with the port. The command portname tracewin as seen in the above example, is used to create a trace window. It has menu items that allow you to dynamically adjust the level of detail being displayed. Also, it has a menu item that brings up a Replay Window. The Replay Window allows you to send or receive any message that has been previously sent or received. It also allows you to save and load Replay session files. The re-receive feature is especially useful for you to debug and develop your interface software without needing to communicate with the actual equipment; the re-receive action simulates reception of the selected messages. The Tcl source code for the tracewin subcommand and for the Replay Window is provided. You may wish to customize it or write your own version(s). For example, you may wish to add menu items that cause custom messages to be sent, or add menu items to display application status. A new option, Logging... under the Tracing menu provides for configuring unattended saving of trace data to files.

The handling of received messages is specified using the whenmsg or whenever subcommands. You register Tcl code to be executed when messages of a specified stream and function are received. The software environment is completely dynamic; messages, and whenmsg handling code can be constructed, modified, and deleted while the application executes.

The put and putl subcommands are used to send messages. You specify callback code to detect failures such as the lack of a response. You do not need to manage your own reply timers. You can optionally specify Tcl code to handle a reply message when sending a message as an alternative to the whenmsg subcommand.

SECS Messages are specified using Tcl SECS Notation (TSN). TSN is similar to the representations of SECS-II messages found in the SEMI Standards, except that it incorporates the list formatting conventions of Tcl. See the manpage TSN for a description.

To parse received data items from TSN, you typically use the rset, vset, lindex, or scan Tcl commands. Also, the lrange and split commands may be useful.

To construct TSN messages for sending, you typically use the list and lappend commands in combination with the usual substitution of variables inside of double quotes. You also use the substitution of command evaluations by enclosing them in square brackets. The append, concat, format, join, lrange, lset and string commands are also used.

You use the close subcommand to terminate a communication connection.

mach1 close
When the application terminates normally, any existing port connections are automatically closed.


secsport portname ?tty_dev? ?baud??
secsport portname terminalServerPort
hsms portname passive socketNum
hsms portname active socketNum ?hostnameOrIP?
The secsport or the hsms command creates a port connection portname. A new Tcl command and a new global data array are created with the name portname. There are four variations of creating a port as listed above. ]

The first variation, the secsport command, creates a SECS-I serial port interface using a tty device on your Unix system, or a COM port on your Windows NT system. The optional tty_dev port specification defaults to COM1 on NT, /dev/tty0 on AIX, /dev/ser1 on QNX, otherwise /dev/tty01. The optional baudrate parameter, baud, defaults to 9600. If you are using a terminal server tty device such as the Xyplex csportd(l), the baudrate parameter has no effect.

Another means of creating a SECS-I interface, is to specify a terminalServerPort. With this variation, SECS-I/SECS-II data exchanges are made through a TCP/IP connection. This variation is usually used to directly attach to a terminal server where an RS-232 port is connected to a remote device. The terminalServerPort is of the form hostnameOrIP_addr:socketNum. Optionally, the terminalServerPort ends with ,S to indicate a server connection. The latter is used in testing, but not to connect to real terminal servers. The software assumes a binary passthrough IP socket connection to the terminal server. Usually, you need to separately configure the terminal server so the port does not perform telnet control character mappings or other canonical processing. For example:

secsport bonder6 xyplex6:2100

If a terminal server connection is lost, the default configuration of the software tries to reconnect periodically. Refer to the active_reconnect and T5 configuration options below.

The passive variation of the hsms command is used to establish an HSMS Single-Session Mode passive service. This is typically used by equipment at startup, to offer a listening socket for the host connection. The socketNum argument, an integer, is the socket number. Typical values are greater than 5000, and are chosen after reviewing /etc/services to avoid conflicts with existing TCP/IP applications. For example, the values 6000 and 7500 should not be used since they are commonly used by X-Windows font servers. The operating system command, netstat -a is used to display which sockets are in use on your system.

The active switch is used with the hsms command to create an HSMS active client. The hostnameOrIP specifies the hostname or IP address of the HSMS passive server that the client should connect to. It defaults to your own workstation which is convenient for testing. You may use the Unix ping command to determine if a hostname or IP address is valid and the server machine is participating in the TCP/IP network. The socketNum argument specifies the port number that the server is listening at.

The global array of the name portname is used to store configuration parameters for the port connection and related data. Do not try to use the same name in your application as a global scalar variable. You may add your own data elements to the array, if you avoid naming conflicts with this software. Also, do not use the variable name secsport. This name is used dynamically to indicate which port has received the current message.

portname abort SsFf ?callback?
This subcommand is used to send an abort reply (function 0) to the indicated primary message SsFf that was received. For tty secsports, the command returns immediately and sends the abort message as event handling occurs. For hsms ports, the abort message is sent before the abort subcommand returns. For either type of connection, the optional callback argument is executed as a background event after the subcommand is completed. See the discussion of callbacks under the put subcommand.
portname close
The close subcommand is used to discontinue communication. If an HSMS connection exists, a Separate.req message is sent before the connection is ended. The close subcommand erases the global array associated with the connection, and removes the portname as a command. The command does not wait for any open message conversations, or queued messages to be sent.
portname lastheader
This subcommand returns the ten byte header data of the last received message. The data is returned as a list of integers. The command is used to send stream 9 messages with the header of a message as data. For example:
 set MHEAD "B [$mach lastheader]"
 $mach put S9F5 $MHEAD

portname online
A newly constructed connection does not function until the online subcommand is issued. You typically configure parameters such as the device ID (DEVID), and set up the handling of asynchronous message reception before enabling communication.

For an HSMS active client, the online subcommand causes an attempt to establish a TCP/IP connection and subsequently a "selected" HSMS connection to the HSMS server. If the attempt to connect fails, or the "Select.req" fails, the online command will return an error. If you want to periodically retry connecting after delays of T5, call the Tcl procedure hsms_wait_online portname. The procedure can also be called by an HSMS server. In this case, it will wait indefinitely for a client to establish a selected connection before returning. Once a successful connection is established, if the connection is lost, the default behavior of an active HSMS client is to periodically attempt to reconnect. See the description of the active_reconnect configuration option to change this.

portname put SsFf?R? ?TSN? ?callback? ?-whenreply tcl_code?
The put subcommand is used to send a SECS-II message. The stream s and function f must be specified. The R is optionally appended to the SsFf term to indicate that you expect a reply message from the other party.

When you send even numbered functions, it is known that you are replying to a primary message, and the reply header is setup for you. The port software saves the latest reply header data for unanswered primary messages. The saved reply headers are indexed by their stream and function. Therefore, your application should reply to a given message before receiving a new message of the same stream and function, or the reply data will be overwritten.

The data of the SECS-II message, TSN, is specified using Tcl SECS Notation (TSN). See the manpage TSN.

If you are expecting a reply, you may use the optional arguments -whenreply tcl_code to register Tcl code to be executed when the reply is received. You can also use the whenmsg subcommand described below. The -whenreply tcl_code will only be executed for the specific message that is received as a reply to your outbound message; the secsport software will match the identification bytes in the message header. This is different behavior than the whenmsg subcommand where the stream and function are matched, but not the identification bytes. The -whenreply tcl_code approach can safely handle the situation of simultaneously expecting more than one reply of a specific stream and function and needing to handle the replies differently. If you are handling all replies of a specific stream and function with the same code, you may find it easiest to use the whenmsg subcommand. When the reply message is received, the tcl_code is executed as described below with the whenmsg subcommand. If the message is not sent successfully, or the reply is not received successfully within the T3 interval, the -whenreply tcl_code is automatically cancelled.

A reply message that is sent with the function value set to 0, is known as an abort message.  The -whenreply tcl_code is executed for abort replies since the received reply message does have matching identification bytes in the message header.  An abort reply is also seen by the optional send callback logic, described below.  When you are using both the send callback and the -whenreply options, you will usually handle all the failure cases from your callback code, and handle the successful replies in your -whenreply tcl_code.  So you will typically test for and ignore an abort message that is received by your -whenreply tcl_code.  If you have been using the whenmsg subcommand for receiving replies, it is easy to forget about the possibility of receiving abort replies with your -whenreply callback since you typically register whenmsg tclcode for only the usual, successful reply function.

With SECS-I communication the put command returns immediately and the message is queued for sending in the background as events are processed. Configuration options are discussed below. If you have left the MULT option false, so that multiple open transactions are not allowed, the new message is not sent until earlier transactions have been completed either by replies having been received, or by timing out. If the MULT option is set true, the message is sent irrespective of any open conversations. This may cause the remote entity to owe more than one reply; a situation that some software cannot properly handle.

The optional callback argument to the put subcommand is used to setup Tcl code to be executed on any of the following conditions: (i) sending the message failed, (ii) the message was sent successfully, and, if the message was sent with a reply expected, (iii) notification that a reply has not been received within the time interval T3, or (iv) a Stream 9 error message or Function 0 message has been received in place of a successful reply.  You do not need to set up reply timers, the software does it for you. In the case of a normal reply message not being received, the callback gets evaluated twice; once at the successful completion of sending, and again when the T3 timer expires, or the other error replies are received.

For SECS-I, in accordance with the standard, the actual timeout criteria of condition (iii) is that the initial block of the reply has not been received in the interval T3, or that any subsequent block has not been received within interval T4 of the previous block.

The optional callback argument is executed as follows. It is treated as a list, concatenated with four more arguments, and then evaluated at a global level by the interpreter. The evaluation method allows you to code multiple Tcl statements in your callback, or to set up additional arguments that preceed the appended ones for your custom procedures. This feature is commonly used. An example would be to pass the name of a global array that holds context information.

The four appended callback arguments are (1) the portname, (2) the SsFf?R? argument, (3) condition, and (4) description. The condition argument will be the literal text send_failure, send_complete, or receive_failure. The description argument provides a text description or diagnostic message of the condition.

Here is an example of using a callback:

proc s1f1_callback {portname sfr reason desc} {
  global debug $portname
  if { $debug } { 
     puts "put_callback: [list $portname $sfr $reason $desc]" 
  if { $reason == "send_complete" } return
  # here on failure
  # disarm a potentially late reply:
  $portname whenmsg S1F2 
  # notify upperlevel software 
  event_report $portname HEARTBEAT FAILURE

proc do_heartbeat {mach} { $mach whenmsg S1F2 "event_report $mach HEARTBEAT OK" $mach put S1F1R "" s1f1_callback }

The T3 configuration option specifies the timeout interval for reply messages. A reply may arrive late even though the callback is executed for the condition receive_failure. If you used the -whenreply tcl_code, your whenreply logic is cancelled at the timeout and is not executed. The secsport software will then see if you have a matching whenmsg established for this stream and function, and it will be executed. If you wish to disarm the whenmsg logic, you may do so in the callback as demonstrated in the example above.

With HSMS communication, the message is sent before the put subcommand returns. Unlike with SECS-I, it is known synchronously whether the message was sent successfully. For compatibility with SECS-I, the optional callback is used exactly as described above to return the send_failure, send_complete, and receive_failure results asynchronously. In addition, the return value of the HSMS put subcommand is a two element list giving the reason and description arguments that are used with callbacks. For example, typical replies are "send_complete success", and "send_failure {port is not connected}". If you may ever use SECS-I instead of HSMS, code your driver using the callback feature for compatibility. If you will always use HSMS, you can take advantage of the simpler synchronous result.

The global variable portname( lastsmsg ) is set to the TSN after the message is successfully sent. Similarly, the latest received message is copied to portname( lastrmsg ). This may be useful for debugging. Also, you can use trace to capture every message sent or received on the port.

The software handles SECS-I line contention in the standard way; the host will defer to an equipment message, it will dispatch the receiving logic for the equipment message, and then it will resume attempting to send the message.

portname putl SsFf?R? ?codes? ?callback? ?-whenreply tcl_code?
The putl subcommand is the same as the put command except the data of the SECS-II message is specified as a list of integer codes. The TSN_to_secs command is used to convert any TSN message to the integer list representation. This command is not commonly used by the application developer. It can be used to send messages that are not proper SECS-II, or that are formatted with extra length bytes.
portname ppbody_put S7Ff?R? PPID bodyType bodySize pathName ?callback? ?-whenreply tcl_code?
The ppbody_put subcommand is used with an HSMS connection to send the S7F3R or S7F6 process program transfer message with the data of the process program being read directly from the file specified by pathName. The subcommand is useful with larger process programs because it avoids large memory allocations which would be needed to work with the data in memory as an ordinary message. The subcommand causes the standard L:2 PPID PPBODY message of S7F3R or S7F6 to be sent. The PPID argument is the process program identifier TSN item; both the type code (usually A) and the identifier text are supplied. The argument bodyType is the TSN type code for the process program data such as B. The supported values are A, B, U1, or I1. The bodySize argument is the length of the process program in bytes. The value can be computed using the Tcl command file size $pathname if it is not known. The use of the optional callback and -whenreply arguments is explained above with the put subcommand. In order to receive larger process programs from S7F3 or S7F5 direct to a file without large memory allocations, the application should set the ppbodyFileMode connection array value to 1 as discussed below.
portname put linktest ?callback?
The put linktest subcommand is only used for an HSMS connection. Sending of a Linktest.req message is initiated. This subcommand is exactly analogous to sending a data message with a reply expected except that the T6 timeout parameter defines the time interval allowed for a reply. The optional callback code is executed with four appended arguments to preserve the similarity with data messages. The SsFf[R] argument will be the term linktest. The reason argument will be any of the above reasons, plus the term reply_received. If the test is successful, the callback is executed twice; once with the reason send_complete and again with the reason reply_received. The reply_received callback is not used with data messages. The secsport software replies to the linktest.req message automatically once the online subcommand has been issued.
portname reset
This subcommand cancels the expectation of any replies, and any associated timers. A SECS-I port is set to the idle state and any messages in the send queue are discarded. The subcommand does not disarm the registered whenmsg code.
portname tracewin
Creates a trace window for the hsms or secsport object. The trace window has a menu with item selections to control the information displayed. The tracewin command is implemented as a Tcl procedure, which can be dynamically loaded by the interpreter after the secsport or hsms commands are first used. This is explained in the section below, entitled AUTOLOAD LIBRARY. The recommended order of setting up a port with a tracing window is (1) use the secsport or hsms command to create your connection object, (2) set the TRACE value in the connection object's array to display the trace information you desire, (3) use the whenmsg subcommand repeatedly to set up your handling of messages that you anticipate receiving, (4) invoke the tracewin subcommand, and (5) use the online subcommand to commence actual communication. An example of actual code is given near the beginning of this page. If the TRACE array element is set after the Trace window is created, the menu item checkboxes for controlling the display will not be accurate.
portname whenever SsFf ?tcl_code?
portname whenmsg SsFf ?tcl_code?
The whenmsg and whenever subcommands are used to setup, modify, or disarm Tcl code that is executed when a message of a specified stream and function are received. If the optional tcl_code argument is not specified, any existing code for the stream and function is cancelled. When the tclcode argument is specified, it is registered for the indicated SsFf, replacing any existing registration. You do not specify an R in the stream and function argument, SsFf used with these subcommands.

At the time the tclcode argument is evaluated, the global variable secsport is set to the value portname, the global variable portname( lastrSFR ) is set to the received SsFf, and the global variable portname( lastrmsg ) is set to the TSN representation of the received SECS-II message. The portname( lastrSFR ) array item ends with an R when the sender expects a reply.

The recommended technique is to call a procedure with the data items that you wish to use as arguments so that the Tcl interpreter makes a copy of their values. Otherwise, the reception of another message may overwrite the current values. Usually in your whenmsg code, you represent the port connection with a variable. It may be a little confusing if you are new to Tcl to write code where the variable name is substituted immediately, but the portname( lastrSFR ) is substituted when the tclcode is evaluated. Use of the escape character \ is described on manpage Tcl. Here are two examples. The whenmsg code is evaluated at a global level so the global variables do not need to be declared global.

# get the $mach substituted  now, but have the data
# substituted when the message arrives:
$mach whenmsg S12F7 \ 
   "process_map \$${mach}(lastrmsg) ; $mach whenmsg again"

# echo a binary string $sp whenever S2F25 "$sp put S2F26 \[set ${sp}(lastrmsg)\]"

As you can see, the tclcode may be more than one programming statement separated by semicolons or newlines. There are other examples on the TSN manpage.

The whenmsg tclcode is discarded after it is used once on the next message of the specified stream and function. The whenmsg again subcommand is used to re-register the same tclcode for use on the next message of the specified stream and function. The whenever tclcode is not discarded after use. The same tclcode is applied to every received message of the specified stream and function until it is cancelled. In other words, the whenever subcommand combines the functionality of the whenmsg tclcode and whenmsg again subcommands into one command.

This software also enables you to establish default whenmsg Tcl code for any stream and function that you have not specifically configured using the whenmsg SsFf command. Just use S0F1 as the SsFf argument to specify default handling for any primary message (odd function) and use S0F2 to specify the default tcl_code for any reply message (even function). Unlike the use of whenmsg for specific streams and functions, the S0F2 and S0F1 specifications are not discarded after use, and you do not need to use whenmsg again to re-register them.

# catch all unexpected primaries:
$mach whenmsg S0F1 \
  "async_inbound \$${mach}(lastrSFR) \$${mach}(lastrmsg)"

proc async_inbound {SFR msg} { switch -exact $SFR { S1F1R { ... } S5F1 { ... } ....

The whenmsg tcl_code is saved in the global array portname using SsFf as the subscript. The inspect application may be used to view this data. However, do not update or delete these elements directly - always use the whenmsg command interface.

There are predefined whenmsg handlers registered for some message types when the connection is created. See the table later in this document.

portname whenmsg again
The tcl_code of the whenmsg subcommand is used to process the next message of the specified type and then is discarded. This subcommand re-registers the code so it is setup for the next message of the specific stream and function.

If you have an error in your tcl_code it interrupts the execution at the point of error. If you execute whenmsg again before the error occurs, the processing of subsequent messages will be insured. However, if the whenmsg again statement occurs after the error, the specific tcl_code is not re-registered. Typically, when developing, you want your logic to stop on the first error so you can diagnose and fix it. However, in production, you want the messages to be processed even if there is an error is some part of the code. Therefore, you make an informed decision where to execute the whenmsg again statement. The whenever subcommand is equivalent to executing the whenmsg again statement at the beginning of your tcl_code.


When you create a port connection object, portname, a global array is created with the name portname. Many of the elements of this array are actually configuration parameters, that you may inspect or modify. We suggest using the inspect application during development for this purpose.

The software is designed to react and utilize your updated configuration values immediately. For example, if you change the BAUD parameter, the RS-232 hardware is reconfigured on the fly, even if you are in the middle of passing a message.

The remainder of this section is a description of the available configuraton options in alphabetical order.

active_reconnect, type: boolean, default: 1
For an HSMS active client, or a SECS-I TCP/IP client of a terminal server, this option specifies whether the client should periodically attempt to reconnect to the server if a connection is established and then lost. The retry interval is specified by T5. The value of T5 should probably be set to a larger value than the default if you have dozens of connections on your workstation. Also, a connection attempt may make your process unresponsive for several minutes if the network, external node, or server is unresponsive. You may wish to make T5 larger if you have more than one HSMS connection or TCP/IP client connection in your process.

BAUD, type: integer, default: 9600
This parameter sets the baud rate for the RS-232 serial communication port. The values 300, 600, 1200, 2400, 4800, 9600, 19200, 38400, and 57600 are supported by this software. Your tty device driver and hardware combination will limit the actual obtainable values. Typically the BAUD parameter has no effect on Terminal Servers which are configured directly at the Terminal Server unit. Baud rate changes may be made at any time, and may disrupt any active message exchange.

DEVID, type: unsigned integer, default: 0
Device Identification. You need to set this parameter to the same value that the other party is using. Standard behavior for equipment is to reply to messages with S9F1 if the Host specified DEVID does not match.

DUPBLKDET, type: boolean, default: 1
Duplicate block detection. If true, duplicate SECS-I blocks will be detected and ignored.

EQUIP, type: boolean, default: 0
Equipment or Host mode. The EQUIP flag is set true for standard equipment behavior such as SECS-I send contention, and the use of Stream 9 messages. The recv_S9F9, recv_S9FX, send_S9F1, and send_S9F9 parameters are reconfigured automatically when the EQUIP is updated. You may change them individually after setting EQUIP.

hsms_reentrant, type: boolean, default: 1
Controls re-entrant execution of callback logic for HSMS connections only. Ordinarily, whenmsg callback logic or send callback logic is designed to return without causing the dispatching of events. When this is the case, there is no possibility of nested callback execution, and this configuration option is irrelevant. There can be dispatching of events within a callback, when using the commands update, vwait, wait, mbx_do_xact, or when using secs_xact with other connections, or if SQL table data is changed and there are executed subscriptions which cause event dispatching by using these commands. Sending of DMH messages or SECS messages using put commands does not cause dispatching of events. If your application is receiving multiple HSMS messages, and causing the dispatching of events from within a callback, and if the hsms_reentrant option is 1, the execution of additional callback logic can occur before the initial callback returns. Usually nested execution is not a problem and it has been the default historic behavior to have it enabled. It can surface as a problem when the same stream and function are received in rapid succession because of the subtle aspects of the whenmsg logic. While a whenmsg or whenever callback is executing, the whenmsg callback is not registered. After the whenmsg or whenever callback completes execution and returns, the whenmsg or whenever callback are re-registered if whenmsg again was called, or if the whenever command was used. If re-entrant callback execution of the same stream and function do occur, and the whenever or whenmsg again commands are in use, the additional messages arrive without the usual whenmsg callback code being registered. Under these circumstances a typical application will send the abort reply with the meaning that the primary message is not being handled by the application. The problem is fixed by recognizing that it is caused by nested execution, and either (1) modifying the use of whenever, whenmsg again or (2) eliminating the dispatching of events during the callback, perhaps by using asynchronous style communication, or (3) setting the hsms_reentrant option to 0. With regards to fix (1), It is possible to keep a callback registered for nested reception by explicitly using the whenmsg SsFf tcl_code command in the callback. This form of the whenmsg command would be used instead of using whenever or whenmsg again. The developer would also need to make sure that the callback logic was designed for re-entrant execution. If you choose to set hsms_reentrant to be 0, you need to be wary of circumstances where your application will not receive from and not respond to a given interface because it is executing from callback logic.

Your application logic can determine how many callbacks are simultaneously active by reading the array element callback_depth. The value of this element is 0 when no callbacks are executing.

In summary, if you are developing an application that dispatches events within whenmsg callbacks, you may wish to consider setting the hsms_reentrant option to 0 to avoid possible issues with nested callback execution.  Typically, this issue is only relevant to more complex applications that use synchronous style communication with multiple SECS or DMH entities.

MULT, type: boolean, default: 0
Multiple Open Transactions. If MULT is set to 1, put messages will be transmitted even if the port is waiting for a reply. There is some software that is not able to handle owing more than one reply. A typical problem is that the SYSTEM identification bytes from the latest primary message are used by the faulty software to send any reply. In this situation, the correct SYSTEM identification bytes for an earlier primary are never received, and the T3 timer is not cancelled. When the timeout occurs, there is confusion since the since the trace log shows that the reply for the stream and function was received. Used for SECS-I only.

ppbodyFileMode, type: boolean, default: 0 for HSMS, not defined for SECS-I
Direct to file Stream 7 process program receiving and sending mode. This option is only for HSMS connections and the value should not be set to 1 for SECS-I. Setting the option to 1 causes the receiving of S7F3 and S7F6 to be handled specially with the process program data being written directly to a file instead of being handled in memory. The standard
message is replaced by the receiving code with a message of the form,
L:2 PPID {L:4 {A pathName } {A bodyType:bodySize } {B ackc7 } {A errtext }}
which is passed to the application instead of the potentially very large message which was actually received. In this substitute message pathName is the pathname of a file containing the process program data, and the bodyType:bodySize value shows the TSN type code used for the body data with the size in bytes. The size will be less than or equal to the 16777215 byte count limit of the Stream 7 transfer message.

If the transfer and saving succeed, the ackc7 value is 0 and the pathName value specifies a file. The application will usually rename the file to a name which is based on the PPID message value. The pathName value is computed by executing the procedure ::dmh::hsms_ppbody_tmpfile. The default logic is to name the file ppbodyReceive.bin. If there is a connection array element named recipe_dir, the value is used as a directory for the temporary file.

There can be errors that prevent success such as disk errors or the SECS message data being improper. If the transfer fails, the ackc7 value is set to non-zero and the errtext value is set with an explanation message. The application can use the ackc7 value as a suitable reply value for S7F4 which is not sent by the receiving logic.

Setting the ppbodyFileMode to 1 also provides a convenient means to send S7F3R or S7F6 using the usual put subcommand instead of having to use the ppbody_put command. If the option is true, and S7F3[R] or S7F6 are being sent, and the structure of the message being sent matches
L:2 {A ppid } {L {A pathName } {A bodyType:bodySize } [more list elements are optional ]}
then the HSMS sending logic will cause the standard L:2 PPID PPBODY message to be sent by directly reading the process program data from the file specified by pathName . This avoids needing to handle the entire message in memory as an ordinary message.

PROTOCOL, type: string, default: "1995"
The usual HSMS protocol is SEMI standard E37. Setting this string to "1993" changes the HSMS protocol to the HSMS-93 protocol as described next. This value must be set before the online subcommand is issued.

Setting the PROTOCOL array element to the value "1993" provides the behavior specified in the document "High-Speed SECS Message Services (HSMS) Working Draft Proposal For Single-Connection Reference Implementation" dated February 15, 1993 with the following exception. The exception was found necessary to insure operational compatibility with GW Associates implementations. According to the draft, HSMS Control Messages should be sent with the R-bit set as for SECS-II messages. However, GW Associates drivers that we have tested do not accept a ConnectionTestAcknowledge message (stype = 6) from an Equipment entity with the R-bit set. Therefore, control messages are always sent with the R-bit clear.

Setting the PROTOCOL array element to the value "1994" provides for a non-standard protocol which uses two length bytes and no control messages.

recv_baddata, type: boolean, default: not defined
Improper Data Receiving Override. The default behavior when improper SECS-II data is received is to send the S9F7 error message and ignore the received message.  An application is able to receive and work with improper message data by defining and setting the array element recv_baddata to the value 1.  When this is done, S9F7 is not sent, and the message reception is processed as if it was normal. If the improper data consists of an ASCII item whose specified length is longer than the passed message data, a proper ASCII string is created by padding the received data with space characters up to a limit of 246 total data bytes. Otherwise, if the passed message data does not exceed 64k bytes, the message data is converted to a proper binary array. Longer values of improper data are ignored, and the message is represented as an empty string.

recv_max, type: integer, default: 0
Optional limit for the size of HSMS messages. Buggy HSMS software can specify a message size up to 4.4 gigabytes which causes the allocation of a memory buffer large enough to receive the message.  If the recv_max array element is set to a value other than 0, its value defines the largest allowed HSMS message size in bytes. If an inbound message header specifies a size larger than the allowed maximum, the software sends a separation request control message and politely closes the connection without doing the allocation. In the usual case, this software is the active HSMS client of buggy equipment, and the connection recovery logic will reconnect within a minute or so.  If you are monitioring the trace window, you will see trace messages about the message size exceeding the maximum and the connection being broken and recovered. The recv_max feature also has the option to execute Tcl code that you register for when the incident occurs. See the description of recv_max_cmd.

recv_max_cmd, type: code string, default: not defined
Optional HSMS size limit callback. If you are using the recv_max size limit for receiving HSMS messages, then you are able to specify Tcl code to be executed whenever the HSMS size limit needs to be imposed.  You assign your own procedure to the array element recv_max_cmd.  When the size limit is exceeded, the connection name and the size of the inbound message are appended as two arguments to your callback code, and then it is evaluated.  This gives you the ability to write to a log file or whatever is appropriate.  For example,
recv_S9F9, type: boolean, default: !EQUIP
S9F9 reply pre-emption. Standard behavior is for a host not to send a reply after receiving S9F9. Unless you override the default, host logic will erase the reply header in the wake of a S9F9 so that a reply cannot be sent.

recv_S9FX, type: boolean !EQUIP
S9FX reply substitution. Unless you override the default, the host logic will call your optional put callback with a receive_failure condition if the equipment sends a S9F1, S9F3, S9F7 or S9F11 in lieu of the standard reply.

RTY, type: unsigned, default: 3
SECS-I retry count. This count establish the maximum number of send retry attempts for block transmission.

send_S9F1, type: boolean EQUIP
Device ID Match Flag. Unless you override the default, equipment logic will send a S9F1 error message when it receives a message that has a DEVID different from its own.

send_S9F7, type: boolean not defined
Data Error Message Override. To comply with the SECS standards, the software will ordinarily send S9F7 error messages when improper SECS-II data is received.  You can disable sending these error messages by defining and setting the array element send_S9F7 to 0. 

send_S9F9, type: boolean EQUIP
S9F9 transaction abort. The default behavior for equipment is to send a S9F9 message if a reply from the host is not received within the equipment's timeout interval.

T1 type: milliseconds, default: 500
SECS-I Receive intercharacter timeout.

T2 type: milliseconds, default: 10000
SECS-I Protocol timeout for block transfer.

T3, type: milliseconds, default: 45000
Reply timeout.

T4, type: milliseconds, default: 45000
SECS-I Inter-block timeout.

T5, type: milliseconds, default: 10000
HSMS Connect Separation timeout. Specifies the delay between connection attempts. This timing parameter is also used for connection retry attempts for a SECS-I TCP/IP client connection. For the later, the default value is 15000.

T6, type: milliseconds, default: 5000
HSMS Control Transaction Timeout.

T7, type: milliseconds, default: 10000
HSMS Not Selected Timeout. If a TCP/IP connection does not transition to an HSMS Selected connection within this interval, the TCP/IP connection is broken off.

T8, type: milliseconds, default: 5000
HSMS Network Intercharacter Timeout. Not used in this implementation.

TRACE, type: unsigned (bits), default 0
Turns on diagnostic output. The display window created using the tracewin subcommand provides an interactive menu to set the TRACE option and a viewing window for the diagnostic output. However, it is possible to utilize the diagnostic output directly using the trace command. We have used this feature on a dial-up connection, when running dmh_wish with the -notk option and not using X-Windows. Diagnostic output is written to three global variables portname(trace), portname(strace), and portname(rtrace), which correspond to general port output, send-related output, and receiving-related output respectively. The TRACE parameter is used as a bitfield. By setting specific bits, the corresponding output is turned on.

General Tracing: Output to portname(trace)

Bit Output Description

0x0001 Read and write calls 0x0002 algorithm state changes

Receive Tracing: Output to portname(rtrace)

Bit Description for Received Messages

0x0100 Header binary dump 0x0200 Header interpretation 0x0400 Stream and Function description 0x0800 Message data binary dump 0x0004 The Message as TSN

Send Tracing: Output to portname(strace)

Bit Description for Sent Messages

0x1000 Header binary dump 0x2000 Header interpretation 0x4000 Stream and Function description 0x8000 Message data binary dump 0x0008 The Message as TSN

Replay Tracing: Used for input to Replay Window

Bit Description

0x0040 Reception data traced to portname(last_recv) 0x0080 Send data traced to portname(last_send)

Logging: Control over output file(s)

0x10000 Save traced data to log file(s). 0x20000 Compress log file when closing.

Even without TRACE being set, the secsport and hsms software keep the state array element updated to the current low-level communication state. One application technique is to use the trace variable command to monitor this array element. The value of this element becomes OFFLINE or LISTENING if the communication connection is lost, or if a SECS-II message cannot be sent.

Saving of trace data to output files is indicated by setting the 0x10000 bit. The saving logic writes each day's output to a distinct file, in the directory named by the traceDir array element.  The traceMax array element controls how many day files are saved per year.  The traceMax array element value can be configured between 1 and 366.  When file saving is initiated, the output filename is set to traceNNN.txt where the NNN value is the current day of the year, 0 to 365, modulo the traceMax value.  If this file already exists and has been written to earlier in the same day, then the output is appended to it, otherwise the file is created as a new file. Note that if the traceMax value is set to 1, each day's output is saved to the same filename, trace000.txt.  If the traceDir and traceMax array elements do not exist when trace data for file logging is first captured, the saving logic creates default values for them.  The default values provide for saving the data from each connection in a separate subdirectory.  When trace data is being written, the 0x20000 bit controls whether the logic attempts to compress the output file when it is closed at the end of the day (midnight).  For compression to occur, the traceMax value must be greater than 1 and a non-blank compression command must exist as the array element traceZipCmd.  The default assignment of traceZipCmd is similar to zip -m tracetxt.zip. This command causes the data file from the previous day to be moved into the tracetxt.zip archive. 

tracewin_maxlines, type: integer, default: 500
This array value can be set to configure the maximum number of text lines that are displayed in the Tcl/Tk trace window.  The default array element value is not set until a Tcl/Tk trace window is created.

tracewin_maxwidth, type: integer, default: not defined
An optional limit for the number of characters that is displayed in a single line of the trace window.  This value can be used to configure the logic that guards against excessive memory use when large messages are displayed on the trace window such as during recipe transfer.  The value is also used when the connection array data is displayed using the "Show Object" menu action. If this value is not defined, the default behavior is to impose a limit of 4000.  Only lines wider than 1000 charaacters are considered for trimming.

TSNSIZE, type: boolean, default: 1
When this flag is true, the TSN representation of received SECS messages are provided with array sizes indicated. If this flag is false, array sizes are not explicitly provided; software can determine the sizes by examining the actual data using commands such as llength.


There is no difference between how these handlers are written and the handlers that you write. All of the usual system behavior such as the configuration of tracing works as expected.  You can deactivate or replace these handlers using the whenmsg or whenever commands as described above.
The received binary message is echoed to the sender.
The system date and time are sent to the requestor. Format: ASCII yymmddhhmmss


The hsms and secsport software is written to conform to:

SEMI E4 - SEMI Equipment Communication Standard 1 - Message Transport (SECS-I)

SEMI E5 - SEMI Equipment Communication Standard 2 - Message Content (SECS-II)



The following statements are made with respect to standard documentation requirements:

Protocol parameters are set as array elements as discussed above.

Timeout parameters are specified with a resolution of 1 millisecond. Performance characteristics limit the actual resolution obtained. All normal parameter ranges are supported; the software will attempt to use any values specified.

There is no fixed maximum size of a message that can be received imposed by this software. However, our test suites do not exercise SECS-I messages in excess of 50K or HSMS messages larger than 10 megabytes.

If a single process is acting as both the Active and Passive sides of an HSMS connection, and a message is sent that is large relative to the size of the TCP/IP buffers, there is some risk that the process will deadlock. This is not usually a concern, and there should be no problem with connections to other processes.

A passive HSMS server accepts multiple TCP connections, but only allows an HSMS-SS selected connection to the first active client. Subsequent clients are given the "Communication Already Active" response code to their select requests. This behavior is exactly the preferred option of SEMI E37 Rejection of Additional Connection Requests by a Passive Mode Entity.

You should document the maximum expected size of messages sent by your application, in order to comply with standard documention requirements.

There is no fixed limit to the number of concurrent open transactions. However, as noted above, the reply header information is indexed by stream and function. If more than one transaction of the same stream and function are open on a single port, the application is not able to reply to the earlier transaction. The application is able to overcome this limit by explicitly saving and restoring the header information through the addition of custom Tcl code.  The SECS/GEM libraries provided by Hume Integration that manage a Tcl SECS server process for other language environments explicitly manage the message header transaction ID and do not have this limitation.

HSMS reject.req behavior is fully supported.


The secsport and hsms commands rely on loading some Tcl support code when they run. Also, the tracewin subcommand, the hsms_wait_online command, and some others, are written as Tcl procedures. The Tcl code procedures are loaded by the interpreter at runtime when the procedures are first used. The SECS software uses the Tcl auto-loading library facility described in the man page library. The library of Tcl code is usually installed in the directory /usr/local/lib/dmh84 along with other procedures used by HIS provided software. When the library is installed in another directory, the environment variable DMH_LIBRARY should be set so the HIS software will add the non-default directory to the auto_path list at startup. Also, if the environmental variable SECS_LIBRARY is defined, the path that it specifies is appended to the interpreter's auto_path variable when the secsport, hsms, or comm commands are first used. The first versions of the runtime software that are found by searching the auto_path list in sequence are the ones that are used. If you customize the runtime library, either source your procedures explicitly, or change the auto_path variable so that your versions are found first.


TSN TSN_to_secs secs_to_TSN


The versions of these commands imbedded in dmh_wish have been developed and licensed for the Tcl/Tk application environment by Hume Integration Software. They are not part of the public Tcl/Tk distribution, and should not be redistributed.


SECS serial communication HSMS SEMI