Sample Automation Script
The following script is provided as a typical automation application. The script is for demonstration and education purposes only. This sample may be copied and edited using common text editors, however Frontline is not responsible for the adverse results.
The sample script is written in TCL1tcl files are based on Tool Command Language (TCL). TCL is an open-source, cross-platform programming language. More information is available at www.tcl.tk.. The script can be translated to any general purpose programming language such as C++.
Read the comments in the script for guidance in developing a script for your applications. You can always contact Frontline technical support for assistance with your ComProbe Automation Server applications.
#
# The following procedures are intended to provide the basics for writing TCL
# scripts that interface to the FTSAutoServer application.
#
# At the bottom of this file is a sample mainloop that utilizes some of these
# procedures.
#
# When you use these procedures in a script, the output has some formatted notations
# that attempt to help visualize what is going on.
#
# Those notations are as follows:
#
# >>> denotes a cmd being sent to the FTSAutoServer application
# <<< denotes a cmd response being received from the FTSAutoServer application
# ...... denotes a Sync Status response being received from the FTSAutoServer
# ### denotes a debug comment
# !!! denotes a Warning or Error condition
#
# There is a set of Command Wrappers for all the automation commands that are
# supported by FTSAutoServer application. Each wrapper has a default timeout
# value in msecs. A different timeout value can be passed to the Command Wrapper
# that will override the default value.
#
###########################################################
# Procedures
###########################################################
proc FTEBaseInit { ipAddr } {
global Connections
global Buffer
global Cid
set Connections(Host) $ipAddr
puts "IP Address: $ipAddr"
puts "Buffer size: [string length $Buffer]\n";
# Setup up the TCP/IP connection
set Cid [Connect $Connections(Host) $Connections(Port)];
# Setup various fileevent handler(s)
fileevent $Cid readable "ReadInput $Cid"
}
proc FTEBaseCleanup {} {
global Cid
# Close the TCP/IP connection with the CPAS automation server
Disconnect $Cid
puts "FtsAutoServer Disconnected"
}
# Connect to the automation server TCP/IP socket.
proc Connect { host port } {
if { [catch { socket $host $port } server] } {
puts stderr "Failed to connect to $host on $port"
return ""
}
return $server
}
# Disconnect from the automation server TCP/IP socket.
proc Disconnect { cid } {
if { ![catch { fileevent $cid readable {} }] } {
close $cid
}
}
# Read a status from the automation server TCP/IP socket.
proc ReadInput { cid } {
global SyncStatusCmd
global CmdStatusArray
global CmdArrayHead
set tempStatus [gets $cid]
# If it is a Cmd Status
if { [string first $SyncStatusCmd $tempStatus] == -1 } {
# Add to Cmd Status Array
array set CmdStatusArray [list $CmdArrayHead $tempStatus]
incr CmdArrayHead
# Else it must be a Sync Status
} else {
# Process Sync Status immediately
SyncStatusCmdHandler $tempStatus
}
}
# Write command to automation server TCP/IP socket.
proc WriteOutput { cid cmd } {
puts $cid $cmd
flush $cid
fileevent $cid writable {}
}
proc SyncStatusCmdHandler { syncStatus } {
global SyncStatusArray
### Debug
###puts "\n### SyncStatusCmdHandler( $syncStatus )\n"
# Convert Status to lower case
set status [string tolower $syncStatus]
set conn ""
set state ""
# Look for string "state="
set index1 [string first "state=" $status]
# Look for ","
set index2 [string first "," $status $index1]
set length [string length $status]
if { $index1 == -1 || $index2 == -1 } {
# Could not find a valid sync status format
return 0
}
set index1 [expr $index1 + 6]
set index2 [expr $index2 - 1]
# Parse out the connection
set conn [string range $status $index1 $index2]
set index1 [expr $index2 + 2]
set index2 [expr $length - 1]
# Parse out the state
set state [string range $status $index1 $index2]
# Get previous sync state for this connection
set prevState [ array get SyncStatusArray $conn ]
# Update the Sync Status array with the new state for this connection
array set SyncStatusArray [list $conn $state]
# Parse out the state
set length [string length $prevState]
if { $length > 0 } {
set index1 [expr [string first " " $prevState] + 1]
set index2 [expr $length - 1]
set prevState [string range $prevState $index1 $index2]
} else {
set prevState 0
}
### Debug
###puts "### status : $status"
###puts "### conn : $conn"
###puts "### state : $state"
###puts "### prevState : $prevState"
#
# At this point we have the current and previous state for this connection
#
puts "\n......"
puts "...... $syncStatus"
puts [format "...... Sync Status\[%d\] changed : %s => %s" $conn [SyncStateColorLookup $prevState] [SyncStateColorLookup $state] ]
# Display various user tips on certain state changes
if 1 {
if { $state == 4 && $prevState < 4 } {
puts "...... Now connect your DUTs."
}
if { $state == 4 && $prevState == 5 } {
puts "...... First send StopSniffing command."
puts "...... Then send SyncStatus OFF command."
}
}
puts "......\n"
# Add any additional handler code here
}
proc GetSyncStateValue { conn } {
global SyncStatusArray
# Get the sync state for this connection
set state [ array get SyncStatusArray $conn ]
# Parse out just the state
set length [string length $state]
if { $length > 0 } {
set index1 [expr [string first " " $state] + 1]
set index2 [expr $length - 1]
set state [string range $state $index1 $index2]
} else {
set state 0
}
return $state
}
namespace export GetSyncStateColor
proc GetSyncStateColor { conn } {
set state [GetSyncStateValue $conn]
return [SyncStateColorLookup $state]
}
namespace export SyncStateColorLookup
proc SyncStateColorLookup { state } {
#
# Note - the state input parameter can be a color that will be converted
# to a valure OR it can be a value that will be converted to a color.
#
if { ![string is integer $state] } {
set state [string tolower $state]
}
switch $state {
0 {
set retVal "Red"
}
1 {
set retVal "Red"
}
2 {
set retVal "Red"
}
"red" {
set retVal 2
}
4 {
set retVal "Green"
}
"green" {
set retVal 4
}
5 {
set retVal "Blue"
}
"blue" {
set retVal 5
}
6 {
set retVal "Grey"
}
"grey" {
set retVal 6
}
7 {
set retVal "Yellow"
}
"yellow" {
set retVal 7
}
default {
if { [string is integer $state] } {
set retVal "Uninitialized"
} else {
set retVal 0
}
}
}
return $retVal
}
namespace export UnexpectedStatusHandler
proc UnexpectedStatusHandler { unexpectedStatus } {
### Debug
puts "\n### UnexpectedStatusHandler( $unexpectedStatus )\n"
# Add any additional handler code here
}
proc SendCmd { cmd params } {
global Cid
# Combine the Cmd and Parameters to form a single cmdLine
set cmdLine [format "%s;%s" $cmd $params]
puts [format ">>> %s\n" $cmdLine]
WriteOutput $Cid $cmdLine
}
namespace export GetCmdStatus
proc GetCmdStatus { cmd {timeout 0} } {
global ConfigSettingsCmd
global StartSniffingCmd
global StopSniffingCmd
global SyncStatusCmd
global NumberDatasources
global Status
#
# Note : cmds that are handled by the Datasource will have a status for each
# datasource in the setup.
# Cmds that are handled by the Core will only have one status.
#
# Check for cmds that are handled by the Datasource
if { $cmd == $ConfigSettingsCmd ||
$cmd == $StartSniffingCmd ||
$cmd == $StopSniffingCmd ||
$cmd == $SyncStatusCmd } {
set statusCnt $NumberDatasources
} else {
set statusCnt 1
}
puts [format "<<< Waiting for status ( timeout = %d msecs )..." $timeout ]
set retVal 0
for { set i 0 } { $i < $statusCnt } { incr i } {
set retVal [WaitForCmdStatus $cmd "" $timeout]
if { $retVal == 1 } {
puts " $Status"
} else {
puts [format "\n!!! WARNING : Timed out waiting for status from : %s\n" $cmd]
}
}
puts "\n"
}
proc WaitForCmdStatus { cmd {status ""} {timeout 0} } {
global Status
###puts "... Waiting for Cmd=$cmd Status=$status"
set retVal 0
set done 0
while { !$done } {
# Wait for a Status reply
set retVal [WaitForStatus $timeout]
# Check for timeout
if { $retVal != 1 } {
set done 1
}
# Convert strings to lower case for comparing below
set cmd [string tolower $cmd]
set status [string tolower $status]
set nextStatus [string tolower $Status]
if { [string first $cmd $nextStatus] != -1 } {
if { [string length $status] > 0} {
if { [string first $status $nextStatus] != -1 } {
set done 1
}
} else {
set done 1
}
}
# If we got a status but it wasn't what we expected then pass it to the Unexpected Status Handler
if { !$done } {
UnexpectedStatusHandler $Status
}
}
return $retVal
}
proc WaitForStatus { {timeout 0} } {
global Status
global CmdStatusArray
global CmdArrayTail
# if no timeout specified use a default of 1 hour
if { $timeout == 0 } {
set timeout 3600000
}
set retVal 0
set Status ""
set currTime [clock clicks -milliseconds]
set expTime $currTime
incr expTime $timeout
###puts [ format "### enter time : %d" $currTime ]
set done 0
while { !$done } {
set nextStatus [ array get CmdStatusArray $CmdArrayTail ]
if { [string length $nextStatus] != 0 } {
array unset CmdStatusArray $CmdArrayTail
incr CmdArrayTail
# example of what nextStatus might look like
# 1 {Start FTS;SUCCEEDED;Timestamp=8/14/2012 2:15:05 PM}
#
# We need to trim the extra stuff from the entry
#
set index [string first " \{" $nextStatus]
if { $index != -1 } {
incr index 2
set length [ expr [string length $nextStatus] - 2 ]
set Status [string range $nextStatus $index $length]
}
}
# Check to see if we even got a Status
if { [string length $Status] > 0 } {
set retVal 1
set done 1
}
if { $timeout != 0 } {
if { [clock clicks -milliseconds] >= $expTime } {
set retVal 0
set done 1
###puts "\n### WARNING - Timed out waiting for status ...\n"
}
}
# Process any pending events and idle callbacks
update
}
###puts [ format "### exit time : %d" [clock clicks -milliseconds] ]
return $retVal
}
namespace export WaitForSyncState
proc WaitForSyncState { conn state {timeout 120000} } {
set retVal 0
if { ![string is integer $state] } {
set state [SyncStateColorLookup $state]
if { $state == 0 } {
puts "!!! ERROR : Invalid Sync State Color"
return retVal
}
}
set currTime [clock clicks -milliseconds]
set expTime $currTime
incr expTime $timeout
###puts [ format "### enter time : %d" $currTime ]
set color [SyncStateColorLookup $state]
puts [format "...... Waiting for connection %d sync state to go %s(%d) ( timeout = %d msecs )..." $conn $color $state $timeout ]
set done 0
while { !$done } {
if { $state == [GetSyncStateValue $conn] } {
set done 1
set retVal 1
}
if { $timeout != 0 } {
if { [clock clicks -milliseconds] >= $expTime } {
set done 1
set retVal 0
puts "\n!!!!!! WARNING : Timed out waiting for sync state ...\n"
}
}
# Process any pending events and idle callbacks
update
}
return retVal
}
###########################################################
# Command Wrappers
###########################################################
proc StartFTS { params {timeout 60000} } {
global Cmd
global StartFTSCmd
global Params
global Status
global NumberDatasources
set Cmd $StartFTSCmd
set Params $params
SendCmd $Cmd $Params
GetCmdStatus $Cmd $timeout
# Extract datasource count from Cmd Status
set Status [string tolower $Status]
set index1 [string first "count=" $Status]
set index2 [string first ";" $Status $index1]
if { $index1 != -1 && $index2 != -1 } {
set index1 [expr $index1 + 6]
set index2 [expr $index2 - 1]
set NumberDatasources [string range $Status $index1 $index2]
}
puts [format " Number of Datasources: %d\n" $NumberDatasources]
}
proc StopFTS { {timeout 60000} } {
global Cmd
global StopFTSCmd
global Params
set Cmd $StopFTSCmd
set Params ""
SendCmd $Cmd $Params
GetCmdStatus $Cmd $timeout
}
proc ConfigSettings { params {timeout 30000} } {
global Cmd
global ConfigSettingsCmd
global Params
set Cmd $ConfigSettingsCmd
set Params $params
SendCmd $Cmd $Params
GetCmdStatus $Cmd $timeout
}
proc StartCapture { {timeout 30000} } {
global Cmd
global StartCaptureCmd
global Params
set Cmd $StartCaptureCmd
set Params ""
SendCmd $Cmd $Params
GetCmdStatus $Cmd $timeout
}
proc SaveCapture { params {timeout 120000} } {
global Cmd
global SaveCaptureCmd
global Params
set Cmd $SaveCaptureCmd
set Params $params
SendCmd $Cmd $Params
GetCmdStatus $Cmd $timeout
}
proc StopCapture { {timeout 120000} } {
global Cmd
global StopCaptureCmd
global Params
set Cmd $StopCaptureCmd
set Params ""
SendCmd $Cmd $Params
GetCmdStatus $Cmd $timeout
}
proc Clear { {timeout 60000} } {
global Cmd
global ClearCmd
global Params
set Cmd $ClearCmd
set Params ""
SendCmd $Cmd $Params
GetCmdStatus $Cmd $timeout
}
proc StartSniffing { {timeout 30000} } {
global Cmd
global StartSniffingCmd
global Params
set Cmd $StartSniffingCmd
set Params ""
SendCmd $Cmd $Params
return [GetCmdStatus $Cmd $timeout]
}
proc StopSniffing { {timeout 30000} } {
global Cmd
global StopSniffingCmd
global Params
set Cmd $StopSniffingCmd
set Params ""
SendCmd $Cmd $Params
GetCmdStatus $Cmd $timeout
}
proc OpenCaptureFile { params {timeout 120000} } {
global Cmd
global OpenCaptureFileCmd
global Params
set Cmd $OpenCaptureFileCmd
set Params $params
SendCmd $Cmd $Params
GetCmdStatus $Cmd $timeout
}
proc CloseCaptureFile { {timeout 60000} } {
global Cmd
global CloseCaptureFileCmd
global Params
set Cmd $CloseCaptureFileCmd
set Params ""
SendCmd $Cmd $Params
GetCmdStatus $Cmd $timeout
}
proc GoLive { {timeout 120000} } {
global Cmd
global GoLiveCmd
global Params
set Cmd $GoLiveCmd
set Params ""
SendCmd $Cmd $Params
GetCmdStatus $Cmd $timeout
}
proc ExitLiveMode { {timeout 120000} } {
global Cmd
global ExitLiveModeCmd
global Params
set Cmd $ExitLiveModeCmd
set Params ""
SendCmd $Cmd $Params
GetCmdStatus $Cmd $timeout
}
proc SyncStatus { params {timeout 30000} } {
global Cmd
global SyncStatusCmd
global Params
set Cmd $SyncStatusCmd
set Params $params
SendCmd $Cmd $Params
# Note - do not wait for a status
}
proc ReSyncStatusCmdNow { {timeout 30000} } {
global Cmd
global ReSyncStatusCmdNowCmd
global Params
set Cmd $ReSyncStatusCmdNowCmd
set Params ""
SendCmd $Cmd $Params
GetCmdStatus $Cmd $timeout
}
proc HTMLExport { params {timeout 1800000} } {
global Cmd
global HTMLExportCmd
global Params
set Cmd $HTMLExportCmd
set Params $params
SendCmd $Cmd $Params
GetCmdStatus $Cmd $timeout
}
proc Export { params {timeout 1800000} } {
global Cmd
global ExportCmd
global Params
set Cmd $ExportCmd
set Params $params
SendCmd $Cmd $Params
GetCmdStatus $Cmd $timeout
}
###########################################################
# FTE_BASE namespace vars
###########################################################
# Some default options
set Connections(Host) 0.0.0.0;
set Connections(Port) 22901;
set Connections(Buffering) full;
set Connections(BufSize) 80000;
set Connections(DataLength) 1000;
set Buffer [string repeat "0" 1000];
set Cid 0
set NumberDatasources 1
set Cmd "";
set Params "";
set Status "";
set CmdArrayHead 0
set CmdArrayTail 0
array set CmdStatusArray [list 0 "initialize"]
array unset CmdStatusArray 0
array set SyncStatusArray [list 1 0]
# The various cmd strings
set StartFTSCmd "Start FTS";
set StopFTSCmd "Stop FTS";
set ConfigSettingsCmd "Config Settings";
set StartCaptureCmd "Start Capture";
set SaveCaptureCmd "Save Capture";
set StopCaptureCmd "Stop Capture";
set ClearCmd "Clear";
set StartSniffingCmd "Start Sniffing";
set StopSniffingCmd "Stop Sniffing";
set OpenCaptureFileCmd "Open Capture File";
set CloseCaptureFileCmd "Close Capture File";
set GoLiveCmd "Go Live";
set ExitLiveModeCmd "Exit Live Mode";
set SyncStatusCmd "Sync Status";
set ReSyncStatusCmdNowCmd "ReSync Status Now";
set HTMLExportCmd "HTML Export";
set ExportCmd "Export";
###########################################################
# Start of sample script
###########################################################
#
# FTEBaseInit is always the first thing that is called passing the appropriate IP Address
#
FTEBaseInit 192.168.0.90
#
# Typically the next thing to do is to start CPAS ( note FTS is a legacy reference )
#
# We must specify the version of Frontline software to be started. You would replace "10" with
# your appropriate version of Frontline sofware. Additionally if you installed Frontline software in a different location
# you would have to modify the path accordingly.
#
set CPASVersion "C:\\Program Files\\Frontline Test System II\\Frontline 10 \\Executables\\Core"
# Note: following are what the Profile setting would be for various technology platforms
# and combinations of technology platforms.
#
# - For BPA low energy:
# set Profile "FTSLE"
#
# - For 802.11 only:
# set Profile "80211"
#
# - For BPA600 only:
set Profile "BPA600"
#
# - For BPA600 Coexisttence
# set Profile "BPA600_Coex"
#
# -For two 802.11 Coexistence
#set Profile "TwoWiFi"
#
#-For SD/SDIO
#set Profile "SDIO"
#
#-For Sodera and 802.11 Coexistence
#set Profile "Sodera_80211_COEX"
#
#-For Sodera
#set Profile "Sodera"
StartFTS [format "%s;%s" $CPASVersion $Profile]
puts "Waiting 60 seconds for datasource initializations..."
after 60000
#
# Set Config settings for BPA 600
#
ConfigSettings [format "IOParameters;BPA600;Master=0x00025b01cb8b;Slave=0x00025b01cbe1"]
#
# Select first device in list for 802.11 datasource ( i.e. ahid=0 )
#
ConfigSettings [format "HWParameters;80211;ahid=0;DevIndex=0"]
#
# Set I/O parameters for 802.11 datasource
#
ConfigSettings [format "IOParameters;80211;ahid=0;Channel=2"]
#
# If you are using a BPA sniffer, you want to turn on Sync Status. Once Sync Status is turned on
# anytime the status of a connection changes, an unsolicited Sync Status Reply is sent back
# through the FTSAutoServer application.
#
SyncStatus "ON"
#
# If you are using BPA sniffer, you would want to Start Sniffing now.
#
StartSniffing
#
# If you are using BPA sniffer, you would probably want to wait until the Sync Status for
# the connection you are interested in goes "Green". This is an example of waiting for an
# unsolicited Snyc Status update. You can send an optional 3rd parameter which is a timeout
# in msecs. Note that the default timeout is 2 minutes.
#
# Also note if you prefer to use the Sync Status values instead of the colors you can pass
# the value as a parameter in place of the color ( e.g. Green = 4 )
#
# Once the Sync Status goes "Green", you would want to have code in your script that causes
# your DUTs to do pairing.
#
WaitForSyncState 1 "Green"
#
# Note: This is here just to allow us to capture for a short period of time.
# There is really no other significance to it being here.
#
puts "Capture for 10 secs ..."
after 10000
#
# This will stop the BPA sniffer, and Sync Status will subsequently go "Red"
#
StopSniffing
#
# Wait for Sync Status to go "Red" before proceding in script.
#
WaitForSyncState 1 "Red"
#
# After Sync State has gone red, stop capture
#
StopCapture
#
# Just before exiting your script, turn Off Sync Status if you turned it On above.
#
SyncStatus OFF
#
# One of the last commands you will probably be doing is to Stop CPAS ( again FTS is a
# legacy reference )
#
StopFTS
#
# FTEBaseCleanup is always the last thing you need to do.
#
FTEBaseCleanup
exit