From: ian Date: Sun, 25 May 2008 20:35:55 +0000 (+0000) Subject: wip multiplex - much better now, including some message changes X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ijackson/git?a=commitdiff_plain;h=27b22e58ab09fbea2d5094eae094eeb5c62007d2;p=trains.git wip multiplex - much better now, including some message changes --- diff --git a/hostside/.cvsignore b/hostside/.cvsignore index eb8ad25..c634ab7 100644 --- a/hostside/.cvsignore +++ b/hostside/.cvsignore @@ -21,5 +21,6 @@ record-l.[ch] record-y.[ch] +persist* +*.log ++realtime.stderr *+dflags.h *.new diff --git a/hostside/README.commands b/hostside/README.commands index 2fac063..7580a79 100644 --- a/hostside/README.commands +++ b/hostside/README.commands @@ -1,13 +1,20 @@ Protocol over new hostside stdin and to multiplexer: - U< ?... means realtime prints that message without any ? - when reflected by multiplexer, one of - + & - is prepended, as follows - - result of command by another client - + result of command by us - & asynchronous - other prefixes - = related to this actual connection + U< possibly-asynchronous messages from realtime + R< ditto, but saved for replay too + S messages to simulation log + + C> commands (reflected to other clients) + L> commands implemented by multiplexer and not reflected to other clients + O< framming output from commands + +Messages from the multiplexer to its clients are always prefixed +with a relevance character, shown as ? below. In messages from +realtime, the ? is absent. ? may be + - result of command by another client + + result of command by us + & asynchronous, not related to a specific command + = related to this actual multiplexer client connection ====================================================================== @@ -24,13 +31,13 @@ POSSIBLY-ASYNCHRONOUS REPORTING OF MESSAGES TO/FROM (MASTER) PIC U< ?picioh in toolong [...] U< ?picioh in msg [...] - U< ?picio out polarity <[[,...]]> literal < and > bracket segs + R< ?picio out polarity <[[,...]]> literal < and > bracket segs U< ?picio out unknown data printed in assoc'd picioh U< ?picio in [] U< ?picio out [] - U< ?picio in-info detect 0|1 decoded `picio in detect[01]' + U< ?detect 0|1 decoded `picio in detect[01]' Suppression (see parse-proto-spec and realtime.c:serial_transmit) nmra data ping/pong special in other out @@ -42,29 +49,32 @@ POSSIBLY-ASYNCHRONOUS REPORTING OF MESSAGES TO/FROM (MASTER) PIC U< ?resolving - S< ?resolution inexplicable - S< ?resolution mispositioned head|tail - S< ?resolution movpos-change-failed / - S< ?resolution problems + R< ?resolution inexplicable + R< ?resolution mispositioned head|tail + R< ?resolution movpos-change-failed / + R< ?resolution problems - S< ?stastate + R< ?stastate U< ?warning [ ] : U< ?warning watchdog : PIC watchdog timer triggered U< ?warning spurious : spurious short circuit (fault) etc. + U< ?warning realtime-stopped SIG*|exit*|E*|... : + U< ?warning realtime-stderr : + U< ?warning realtime-stderr-unavailable : U< ?train signalling-problem .... U< ?train signalling-problem : - S< ?train forwards|backwards at [-]:+- - S< ?train has [-][/].... + R< ?train at [-]:+- forwards|backwards + R< ?train has [-][/].... is * for det_expected ! for foredetect @ for det_ignore - S< ?movpos feat point|relay - S< ?movpos position moving - S< ?movpos position stable + R< ?movpos feat point|relay + R< ?movpos position moving + R< ?movpos position stable may be ? for unknown U< ?debug : @@ -72,27 +82,27 @@ POSSIBLY-ASYNCHRONOUS REPORTING OF MESSAGES TO/FROM (MASTER) PIC MESSAGES TO SIMULATION LOG - L picioh in suppressed [...] - L picioh in suppressed-detect [...] - L command-in .... - L timestamp . - L timer-event . - L 0|1 detection, same segment as last suppressed-detect + S picioh in suppressed [...] + S picioh in suppressed-detect [...] + S command-in .... + S timestamp . + S timer-event . + S 0|1 detection, same segment as last suppressed-detect ====================================================================== COMMANDS AND RESPONSES - P> [...] + C> [...] results in: - R< ?nak unknown-command|permission-denied|invalid-syntax [: ] - R< ?executing + O< ?nak [] [: ] + O< ?executing [...] consequential messages including picio, signalling problems etc. - then one of these - R< ?ack ok - R< ?ack - R< ?ack [] : ... - R< ?ack SignallingPredictedProblem \ + which may be U< R< then one of these + O< ?ack ok + O< ?ack + O< ?ack [] : ... + O< ?ack SignallingPredictedProblem \ |? : ... when these come through the multiplexer, everything which is a @@ -107,18 +117,17 @@ COMMANDS AND RESPONSES MULTIPLEXER FACILITIES - M< = indicates messages from the multiplexer about this - M> = specific client connection - - M< =connected - M< =permission normal|super - or - M< =denied + U< =connected } on + U< =permission normal|super } initial + or } connection + U< =denied } and later perhaps - A< =failed : regardless of selected message patterns - otherwise there is no need to quit - just send eof + U< =failed : } regardless of + U< =failed client-io : } selected message patterns + } and then connection closed + There is no need to ask to quit - just send eof - M> select [~]... + L> select [~]... first match wins; ~ discards the message. in pattern -+./:0-9a-zA-Z match themselves @@ -129,19 +138,20 @@ MULTIPLEXER FACILITIES if no match, it is as if the following patterns were appended ?info ?warning ~-* ~&* ~+debug * - M> replay [~]... - M< +executing replay - M< - M< +ack replay ok + L> replay [[~]...] if none, uses result from select + O< +executing replay + R< + + O< +ack replay ok MULTIPLEXER-IMPLEMENTED FUNCTIONALITY AFFECTING WHOLE SYSTEM - P> [!] ... - R< ?nak|executing...ack... as above + C> [!] ... + O< ?nak|executing...ack... as above - C> !realtime kill|finish|start|start-manual - C> !save + C> !realtime kill|start|start-manual + C> !dump ====================================================================== @@ -149,20 +159,20 @@ MULTIPLEXER-IMPLEMENTED FUNCTIONALITY AFFECTING WHOLE SYSTEM DIRECT NMRA AND PIC INSTRUCTIONS Example (always the same msg): - P> !nmra [] [...]] nmra speed28 3 13 1 - P> !nmra [] [=] nmra =0348 - P> !nmra [] [:] nmra :03484b - P> !nmra [] [_] nmra _7f7f00644197 + C> !nmra [] [...]] nmra speed28 3 13 1 + C> !nmra [] [=] nmra =0348 + C> !nmra [] [:] nmra :03484b + C> !nmra [] [_] nmra _7f7f00644197 in each case (if present) is * or % and indicates that the message should be put in the retransmission cycle, and cancels any previous message with the same . may be empty. * indicates urgent - P> !nmra + C> !nmra cancels the relevant retransmission. Example (always the same msg): - P> !pic = pic =a003 - P> !pic [] pic point 3 + C> !pic = pic =a003 + C> !pic [] pic point 3 the latter for commands with no `...' in README.protocol only Keen readers will observe that diff --git a/hostside/commands.c b/hostside/commands.c index 36386a0..0fcc7a2 100644 --- a/hostside/commands.c +++ b/hostside/commands.c @@ -307,19 +307,21 @@ static int cmd_invert(ParseState *ps, const CmdInfo *ci) { void command_doline(ParseState *ps, CommandInput *cmdi_arg) { int r; + const char *cmdline; simlog("command-in %s\n",ps->remain); simlog_flush(); current_cmd= 0; - if (!ps->remain[0]) return; + cmdline= ps->remain; + if (!cmdline[0]) return; r= ps_word(ps); assert(!r); current_cmd= some_lookup(ps,toplevel_cmds); if (!current_cmd) { - ouprintf("nack unknown-command\n"); + ouprintf("nack UnknownCommand\n"); return; } - ouprintf("executing %s\n",current_cmd->name); + ouprintf("executing %s\n",cmdline); if (sta_state < Sta_Run && !(current_cmd->xarg & CIXF_ANYSTA)) { ouprintf("ack %s InvalidState : layout not ready\n",current_cmd->name); return; diff --git a/hostside/errorcodes.h.gen b/hostside/errorcodes.h.gen index d2aaf5b..2eaf630 100755 --- a/hostside/errorcodes.h.gen +++ b/hostside/errorcodes.h.gen @@ -11,7 +11,12 @@ InvalidState SignallingPredictedProblem SignallingHorizonReached + LimitExceeded + SystemFailed + UnknownCommand + PermissionDenied + HostSupportSystemsProblem ); diff --git a/hostside/multiplex b/hostside/multiplex index 6b8056f..5293905 100755 --- a/hostside/multiplex +++ b/hostside/multiplex @@ -1,18 +1,44 @@ -#!/usr/bin/tclsh8.4 +#!/usr/bin/tcl # per connection: # c/$conn(super) 0 or 1 # c/$conn(ipaddr) # [msel/$conn "$msg "] 0 or 1 +# [mreplay/$conn "$msg "] 0 or 1 during replay only +# c/$conn(q) [list $inputline ...] # # globals: -# $cmdqueue [list $conn $cmd ...] -# $master socket -# $permissions [list allow|super|deny $ipaddrhex $maskhex ...] - -#---------- i/o to realtime ---------- +# $queueing [list $conn ...] +# $master socket +# $permissions [list allow|super|deny $ipaddrhex $maskhex ...] +# $realtime pipes +# $replay("$pri $key") $rhs $pri is \d\d; causes replay of "$key $rhs" +# $detect0($seg) unset -> 1 or irrelevant; [after ...] +# $conns($conn) 1 +# +# configs set directly in multiplex-config: +# $records [list filename.record ...] +# $detectlag +# +# $conn is in $queueing iff c/$conn(q) is nonempty +# +# globals relating to realtime's command execution state: +# awaiting awaiting executing global +# idle executing/nak ack internal cmd dead +# +# $realtime set set set ? unset +# $currentcmd unset $cmd $cmd $cmd unset +# $currentconn unset $conn or {} $conn or {} $conn unset +# $executing 0 0 1 1 0 +# +# replay priorities and messages: +# 10 stastate +# 50 resolution .... +# 60 movpos ... +# train ... +# 70 detect 0|1 -proc cmdqueue-check {args} { } +#---------- replay, general utilities, etc. ---------- proc compile-glob-patterns {pats procname} { if {[llength $pats] > 20 || [string length $pats] > 200} { @@ -36,20 +62,107 @@ proc compile-glob-patterns {pats procname} { append def { {^[-&]\S|^\+debug\s} { return 0 }} "\n" append def " }\n" append def " return 1\n" - puts $def proc $procname {m} $def } -proc cmd/select {conn args} { +proc nargs {l {n 0}} { + if {[llength $l]!=$n} { cmderr BadCmd "wrong number of arguments" } +} + +proc xmit-relevantly {m} { + global executing currentconn conns + if {$executing} { + puts "<* $m" + set myconn $currentconn + trapping xmit-only-noreport $currentconn +$m + set othersm -$m + } else { + puts "<& $m" + set myconn {} + set othersm &$m + } + foreach conn [array names conns] { + if {[string compare $myconn $conn]} { + trapping xmit-only-noreport $conn $othersm + } + } +} + +#---------- multiplexer-implemented command ---------- + +proc local/select {conn args} { upvar #0 c/$conn c compile-glob-patterns $args msel/$conn } +proc global/!dump {conn args} { + nargs $args + if {[catch { save-dump } emsg]} { + cmderr HostSupportSystemsProblem "failed to save dump: $emsg" + } +} + +proc local/replay {conn args} { + global replay + if {[llength $args]} { + rename msel/$conn mreplay/$conn ;# park it here for a moment + compile-glob-patterns $args msel/$conn + } + foreach pk [lsort [array names replay]] { + set m "+[string range $pk 3 end] $replay($pk)" + xmit-only $conn $m + } + if {[llength $args]} { + rename mreplay/$conn msel/$conn + } +} + +proc global/!realtime {conn args} { + nargs $args 1 + switch -exact [lindex $args 0] { + kill { realtime-failed killed "termination requested by command" } + start { realtime-start {} } + start-manual { realtime-start -m } + default { cmderr BadCmd "unknown !realtime subcommand" } + } +} + #---------- connection and commands ---------- proc client-inputline {conn l} { + global queueing + upvar #0 c/$conn c + puts "$conn> $l" + client-disable-readable $conn + if {![llength $c(q)]} { lappend queueing $conn } + lappend c(q) $l + after idle process-queues +} + +proc process-queues {} { + global queueing currentcmd + while {![info exists currentcmd] && [llength $queueing]} { + set conn [lindex $queueing 0] + set queueing [lrange $queueing 1 end] + + upvar #0 c/$conn c + if {![llength $c(q)]} continue + + set l [lindex $c(q) 0] + set c(q) [lrange $c(q) 1 end] + if {[llength $c(q)]} { + lappend queueing $conn + } else { + client-enable-readable $conn + } + + trapping process-command $conn $l + } +} + +proc process-command {conn l} { + global currentcmd currentconn realtime executing global errorInfo errorCode - global cmdqueue upvar #0 c/$conn c set cmd ? set r [catch { @@ -57,35 +170,70 @@ proc client-inputline {conn l} { set l [string trim $l] if {![string length $l]} return if {![regexp {^((!?)[-a-z0-9]+)(?:\s.*)?$} $l dummy cmd priv]} { - error "improper command name" {} {TRAIN CMDNAK invalid-syntax} + error "improper command name" {} {TRAIN CMDNAK BadCmd} } if {[regexp {[^ \t!-~]} $l]} { - error "improper character" {} {TRAIN CMDNAK invalid-syntax} + error "improper character" {} {TRAIN CMDNAK BadCmd} } if {[string length $priv] && !$c(super)} { - error "" {} {TRAIN CMDNAK permission-denied} + error "" {} {TRAIN CMDNAK PermissionDenied} } - if {![catch { info args cmd/$cmd }]} { - xmit $conn "+executing $cmd" - eval [list cmd/$cmd $conn] [lrange [split $l] 1 end] + + if {![catch { info args global/$cmd }]} { + set currentcmd $cmd + set currentconn $conn + set executing 1 + xmit-relevantly "executing $cmd" + eval [list global/$cmd $conn] [lrange [split $l] 1 end] + } elseif {![catch { info args local/$cmd }]} { + xmit-only $conn "+executing $cmd" + eval [list local/$cmd $conn] [lrange [split $l] 1 end] + } elseif {![info exists realtime]} { + error "" {} {TRAIN CMDNAK realtime-not-running} } else { - lappend cmdqueue $conn $l - after idle cmdqueue-check + set currentcmd $cmd + set currentconn $conn + if {[catch { + puts ">> $l" + puts $realtime $l + } emsg]} { + if {[string match {POSIX EPIPE *} $errorCode]} { + realtime-failed EPIPE "" + } elseif {[string match {POSIX *} $errorCode]} { + realtime-failed [lindex $errorCode 1] \ + "write failed: [lindex $errorCode 2]" + } else { + realtime-failed ?write-[lindex $errorCode 0] \ + "puts failed ($errorCode): $emsg" + } + } + return } } emsg] if {$r==2} return - if {$r==0} { xmit $conn "+ack $cmd ok"; return } + if {$r==0} { + set m "ack $cmd ok" + if {$executing} { + xmit-relevantly $m + set executing 0 + unset currentconn + unset currentcmd + } else { + xmit-only $conn +$m + } + return + } switch -glob $errorCode { {TRAIN REPORTED*} { } {TRAIN CMDNAK*} { set el [concat [list +nack] [lrange $errorCode 2 end]] if {[string length $emsg]} { append el ": " $emsg } - xmit $conn "$el" + xmit-only $conn "$el" } {TRAIN CMDERR*} { set el [concat [list +ack $cmd] [lrange $errorCode 2 end]] - xmit $conn "$el : $emsg" + xmit-only $conn "$el : $emsg" } * { set ei $errorInfo; set ec $errorCode @@ -95,7 +243,17 @@ proc client-inputline {conn l} { } } -proc client-eof {conn} { kill-conn $conn "" } +proc client-eof {conn} { + puts "$conn>\$" + kill-conn $conn "" +} + +proc client-enable-readable {conn} { + fileevent $conn readable [list trapping readable client $conn] +} +proc client-disable-readable {conn} { + fileevent $conn readable {} +} #---------- general IO ---------- @@ -104,26 +262,44 @@ proc readable {whatfor conn} { if {[eof $conn]} { $whatfor-eof $conn } } -proc xmit-always {conn msg} { puts $conn $msg } +proc xmit-puts {conn msg} { + global conns errorInfo + if {![info exists conns($conn)]} return + if {[catch { puts -nonewline $conn $msg } emsg]} { + kill-conn $conn "=failed client-io : $emsg" + error $emsg $errorInfo {TRAIN REPORTED} + } +} -proc xmit {conn msg} { +proc xmit-only-always {conn msg} { + puts "<$conn $msg" + xmit-puts $conn "$msg\n" +} +proc xmit-only-noreport {conn msg} { append msg "\n" - if {[msel/$conn $msg]} { puts -nonewline $conn $msg } + if {[msel/$conn $msg]} { xmit-puts $conn $msg } +} +proc xmit-only {conn msg} { + puts "<$conn $msg" + xmit-only-noreport $conn $msg } #---------- error handling ---------- proc kill-conn {conn msg} { + global conns queueing upvar #0 c/$conn c - global cmdqueue - if {[string length $msg]} { catch { xmit-always $conn $msg } } + catch { unset conns($conn) } ;# do this first to stop any recursion + puts "<$conn\$ closing : $msg" + if {[string length $msg]} { catch { xmit-only-always $conn "$msg" } } catch { close $conn } + if {[set ix [lsearch -exact $queueing $conn]] >= 0} { + set queueing [lreplace $queueing $ix $ix] + } catch { unset c } catch { rename msel/$conn {} } + catch { rename mreplay/$conn {} } set qn {} - foreach {tconn tl} $cmdqueue { - if {[string compare $tconn $tl]} { lappend qn $tconn $tl } - } set cmdqueue $qn } @@ -154,7 +330,7 @@ proc trapping {proc conn args} { if {![catch { uplevel #0 [list $proc $conn] $args } r]} { return $r } switch -glob $errorCode { {TRAIN EXPECTED*} { kill-conn $conn "=failed : $r" } - {TRAIN SILENT*} { kill-conn $conn } + {TRAIN REPORTED*} { kill-conn $conn "" } * { report-unexpected {UNEXPECTED ERROR} $r kill-conn-ierr $conn @@ -162,6 +338,164 @@ proc trapping {proc conn args} { } } +#---------- realtime subprocess ---------- + +proc realtime-failed {k m} { + global realtime currentcmd currentconn executing + global errorInfo errorCode + # if $m is "", use wait status + if {![string length $m]} { + set r [catch { + fconfigure $realtime -blocking 1 + close $realtime + } emsg] + if {!$r} { + set m "unexpectedly closed pipe ?!" + set k unexpected + } elseif {[string match {CHILDSTATUS*} $errorCode]} { + set m "exited with status [lindex $errorCode 2]" + set k "exit[lindex $errorCode 2]" + } elseif {[string match {CHILDKILLED*} $errorCode]} { + set m "killed by signal [lindex $errorCode 3]" + set k [lindex $errorCode 2] + } else { + set m "failed confusingly ($errorCode): $emsg" + set k ?wait-[lindex $errorCode 0] + } + } else { + catch { close $realtime } + } + puts "<<\$ $k : $m" + catch { unset realtime } + if {[catch { + set sef [open +realtime.stderr r] + while {[gets $sef l] >= 0} { + xmit-relevantly "warning realtime-stderr : $l" + } + close $sef + unset sef + } emsg]} { + if {![string match {POSIX ENOENT *} $errorCode]} { + xmit-relevantly "warning realtime-stderr-unreadable : $emsg" + } + catch { close $sef } + } + xmit-relevantly "warning realtime-stopped $k : $m" + if {[catch { + save-dump + } emsg]} { + xmit-relevantly "warning dump-failed : $emsg" + } + if {$executing} { + xmit-relevantly "ack $currentcmd SystemFailed realtime : $m" + set executing 0 + } elseif {[info exists currentcmd]} { + xmit-relevantly "nak SystemFailed realtime : $m" + unset currentcmd + unset currentconn + } + realtime-notrunning-init +} + +proc realtime-notrunning-init {} { + realtime-inputline dummy "stastate -" ;# fake this up +} + +proc realtime-start {xopts} { + global realtime records + if {[info exists realtime]} { + cmderr InvalidState "realtime already running" + } + set cl [concat \ + [list 2> +realtime.stderr ./realtime -v2] \ + $xopts $records] + if {[catch { + set realtime [open |$cl r+] + fconfigure $realtime -translation binary -buffering line -blocking 0 + fileevent $realtime readable [list readable realtime $realtime] + } emsg]} { + realtime-failed start $emsg + error "realtime failed : $emsg" "" {TRAIN REPORTED} + } +} + +proc realtime-eof {dummy} { realtime-failed EOF "" } + +proc detect0timeout {seg} { + global replay + upvar #0 detect0($seg) d0 + unset d0 + set key "detect $seg" + set replay("70 $key") 0 + xmit-relevantly "$key 0" +} + +proc clear-replay-detects {} { + global replay + foreach k [array names replay] { + if {[regexp {^.. detect } $k]} { unset replay($k) } + } +} + +proc realtime-inputline {dummy l} { + global detectlag replay + + puts "<< $l" + + if {[regexp {^(detect (\w+)) ([01])$} $l dummy key seg value]} { + upvar #0 detect0($seg) d0 + catch { after cancel $d0 } + if {$value} { + if {[info exists d0]} { unset d0; return } + } else { + set d0 [after $detectlag detect0timeout $seg] + return + } + set pri 70 + } elseif {[regexp {^(stastate) (.*)$} $l dummy key value]} { + switch -exact -- $value { + Settling { clear-replay-detects } + Resolving { catch { unset replay("50 resolution") } } + } + set pri 10 + } elseif {[regexp {^(resolution) (.*)$} $l dummy key addvalue]} { + set pri 50 + } elseif {[regexp -expanded { + ^( movpos \s \S+ \s (?: feat \s \S+ | position) | + train \s \S+ \s (?: has | at ) | + picio \s out \s polarity + ) \s (.*) $ + } $l dummy key value]} { + set pri 60 + } + if {[info exists key]} { + set pk "$pri $key" + upvar #0 replay($pk) rep + if {[info exists value]} { + set rep $value + } else { + append rep $value + } + } + + switch -regexp -- $l { + {^executing\s|^nak\s} { + set executing 1 + } + } + + xmit-relevantly $l + + switch -regexp -- $l { + {^ack\s|^nak\s} { + set executing 0 + unset currentcmd + unset currentconn + after idle process-queues + } + } +} + #---------- new connections ---------- proc find-permission {ipaddr} { @@ -174,8 +508,11 @@ proc find-permission {ipaddr} { } proc connected {conn} { + global conns upvar #0 c/$conn c fconfigure $conn -blocking 0 -buffering none -translation auto + set c(q) {} + set conns($conn) 1 set perm [find-permission $c(ipaddr)] switch -exact $perm { deny { finally $conn =denied; return } @@ -185,14 +522,15 @@ proc connected {conn} { } compile-glob-patterns {} msel/$conn - xmit-always $conn =connected - xmit-always $conn "=permission [lindex {normal super} $c(super)]" - fileevent $conn readable [list trapping readable client $conn] + xmit-only-always $conn =connected + xmit-only-always $conn "=permission [lindex {normal super} $c(super)]" + client-enable-readable $conn } proc newconn {conn ipaddr port} { upvar #0 c/$conn c catch { unset c } + puts "$conn new-client $conn $ipaddr $port" set c(ipaddr) $ipaddr trapping connected $conn } @@ -240,10 +578,13 @@ proc binding {addr blist} { } proc startup {} { - global cmdqueue + global queueing executing catch { close $master }; catch { unset master } - source multiplex-config - set cmdqueue {} + uplevel #0 source multiplex-config + set queueing {} + set executing 0 + realtime-notrunning-init + commandloop -async -prompt1 { return "% " } -prompt2 { return "> " } } startup diff --git a/hostside/multiplex-config b/hostside/multiplex-config index 13c47c4..4e87d3a 100644 --- a/hostside/multiplex-config +++ b/hostside/multiplex-config @@ -10,3 +10,8 @@ binding 127.0.0.1 { super 127.0.0.1 deny 0.0.0.0/32 } +set records { + shinkansen.speeds.record + homes.record +} +set detectlag 100 diff --git a/hostside/safety.c b/hostside/safety.c index fb0fd3f..e67f85a 100644 --- a/hostside/safety.c +++ b/hostside/safety.c @@ -965,10 +965,11 @@ ErrorCode predict(Train *tra, struct timeval tnow, unsigned flags, /*========== reporting position and ownership ==========*/ void report_train_position(Train *tra) { - ouprintf("train %s %s at %s%s:%d+-%d\n", - tra->pname, tra->backwards ? "backwards" : "forwards", + ouprintf("train %s at %s%s:%d+-%d %s\n", + tra->pname, tra->foredetect->tr_backwards?"-":"", - tra->foredetect->i->pname, tra->maxinto, tra->uncertainty); + tra->foredetect->i->pname, tra->maxinto, tra->uncertainty, + tra->backwards ? "backwards" : "forwards"); } static int report_getmovpos(TrackLocation *t, TrackAdvanceContext *c, diff --git a/hostside/startup.c b/hostside/startup.c index dd6fd0c..0cdc945 100644 --- a/hostside/startup.c +++ b/hostside/startup.c @@ -292,8 +292,7 @@ static SegmentNum on_pic_detect_prep(int detyn, int objnum) { if (!(picio_send_noise <= 1 && segments[segn].owner && segments[segn].det_ignore)) - ouprintf_only("picio in-info detect %d %s\n", - detyn, info_segments[segn].pname); + ouprintf_only("detect %s %d\n", info_segments[segn].pname, detyn); return segn; }