
proc APSOpenTelnetStreamHelp {} {
    return "Usage: APSOpenTelnetStream -IPaddress <address>\n\[-GreetingLines <number>\]\nReturns a value for the stream ID which should be used in subsequent calls to related procedures APSWriteToTelnetStream and CloseTelnetStream.\n\nIPaddress is an IP address that can be used by a telnet command;\nGreetingLines is the number of greeting lines expected when logging on to telnet for the particular machine. The default value is 5, which corresponds to the hp VSA. If the actual number of telnet greeting lines is different from what is specified then the procedure will hang up or garbage will be returned in APSWriteToTelnetStream commands.\n\nexample of APS<...>Telnet commands:\nset streamID \[APSOpenTelnetStream -IPaddress hpvecsr\]\nAPSWriteToTelnetStream -streamID \$streamID -command freq:Cent 2e9\nAPSCloseTelnetStream -streamID \$streamID"
}

proc APSOpenTelnetStream {args} {
    set IPaddress ""
    set GreetingLines 5
    APSStrictParseArguments {IPaddress GreetingLines}
    if {![string length $IPaddress]} {
        return -code error "APSOpenTelnetStream: No IPaddress specified"
    }
#    if [catch {ping $IPaddress} result] {
#        return -code error "APSOpenTelnetStream: $result. $IPaddress not responding."
#    }
    if {[catch {open "|telnet $IPaddress" r+} streamID]} {
        return -code error "APSOpenTelnetStream: $streamID"
    }
# five greeting lines must be read.
# If there are not exactly 5 greeting lines then either
# the extra gets statements hangs up tcl
# or the missing gets causes junk to be read by the SCPI parser.

    for {set i 0} {$i < $GreetingLines} {incr i} {
        if {[eof $streamID]} {
            return -code error "OpenTelnetStream: unable to open $IPaddress"
        }
        if {[catch {gets $streamID} result]} {
            return -code error "OpenTelnetStream: $result"
        }
    }
    return $streamID
}
proc APSWriteToTelnetStreamHelp {} {
    return "Usage: APSWriteToTelnetStream -command <string> -streamID <value>\n\nwrites a command to the telnet stream. If the command is a query command, then the results of the query is the value returned."
}
proc APSWriteToTelnetStream {args} {
    set command ""
    set streamID ""
    APSStrictParseArguments {command streamID}
    if {![string length $command]} {
        return -code error "APSWriteToTelnetStream: No command specified"
    }
    if {![string length $streamID]} {
        return -code error "APSWriteToTelnetStream: No streamID specified"
    }
    set returnList ""
    # puts stderr "APSWriteToTelnetStream: $command"
    while 1 {
        set semicolonIndex [string first \; $command]
        if {$semicolonIndex>=0} {
            set remainder [string range $command [expr {$semicolonIndex+1}] end]
            set command [string trim [string range $command 0 [expr {$semicolonIndex-1}]]]
        } else {
            set remainder ""
        }
        set command [string trim $command " \001\002\003\004\005\006\007\010\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\n\r"]
        if {[catch {puts $streamID $command
            flush $streamID} result]} {
            return -code error "APSWriteToTelnetStream: $result"
        }
        after 1000
        while 1 {
            if {[catch {gets $streamID} result]} {
                return -code error "APSWriteToTelnetStream: $command"
            }
            set result [string trim $result " \001\002\003\004\005\006\007\010\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\n\r"]
            # puts stderr "result and command: |${result}|${command}|"
            if {[string compare $command $result]==0} {
                break
            }
        }
        # puts stderr "SCPI echo: $result"
        # after 1000
        if {[regexp {\?} $command]} {
            if {[catch {gets $streamID} result]} {
                return -code error "APSWriteToTelnetStream: $result"
            }
            set result [string trim $result " \001\002\003\004\005\006\007\010\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\n\r"]
            # puts stderr "result: $result"
            lappend returnList $result
        } 
        if {[string length $remainder]==0} {
            if {[llength $returnList]>1} {
                return $returnList
            }
            return [lindex $returnList 0]
        }
        set command $remainder
    }
}

proc APSCloseTelnetStreamHelp {} {
    return "Usage: APSCloseTelnetStreamHelp -streamID <value>\n\nCloses the telnet session connected to the stream ID specified."
}
proc APSCloseTelnetStream {args} {
    set streamID ""
    APSStrictParseArguments {streamID}
    if {![string length $streamID]} {
        return -code error "APSCloseTelnetStream: No streamID specified"
    }
    catch {close $streamID}
# for some reason the close command on the hpvec produces
# an error code even when there is no error.
#    if [catch {close $streamID} result] {
#        return -code error "APSCloseTelnetStream: $result"
#    }
    return
}

