feat: While using Flex & Steppir or Ultrabeam can prevent transmit when antenna is moving
This commit is contained in:
@@ -352,6 +352,7 @@ type FlexController interface {
|
||||
SetRFPower(int) error
|
||||
SetTunePower(int) error
|
||||
SetTune(bool) error
|
||||
SetTXInhibit(bool) error
|
||||
SetVOX(bool) error
|
||||
SetVOXLevel(int) error
|
||||
SetVOXDelay(int) error
|
||||
|
||||
@@ -109,6 +109,7 @@ type flexTX struct {
|
||||
tunePower int
|
||||
tune bool
|
||||
transmitting bool // interlock state == TRANSMITTING
|
||||
inhibit bool // transmit inhibited (e.g. while a motorized antenna moves)
|
||||
voxEnable bool
|
||||
voxLevel int
|
||||
voxDelay int
|
||||
@@ -1708,6 +1709,14 @@ func (f *Flex) SetTune(on bool) error {
|
||||
return f.txSet(cmd, "tune", func(t *flexTX) { t.tune = on })
|
||||
}
|
||||
|
||||
// SetTXInhibit blocks (on=true) or allows transmission at the radio. Used to keep
|
||||
// the operator from keying while a motorized antenna's elements are moving —
|
||||
// SmartSDR refuses to transmit while inhibit is set, so it holds even against a
|
||||
// footswitch or an external keyer, which a software PTT block could not.
|
||||
func (f *Flex) SetTXInhibit(on bool) error {
|
||||
return f.txSet("transmit set inhibit="+boolFlex(on), "inhibit", func(t *flexTX) { t.inhibit = on })
|
||||
}
|
||||
|
||||
func (f *Flex) SetVOX(on bool) error {
|
||||
return f.txSet("transmit set vox_enable="+boolFlex(on), "vox_enable", func(t *flexTX) { t.voxEnable = on })
|
||||
}
|
||||
|
||||
+15
-1
@@ -286,19 +286,33 @@ func (n *icomNet) ctrlPump() {
|
||||
switch icnLE.Uint16(buf[4:]) {
|
||||
case 0x07: // ping
|
||||
_, _ = n.ctrl.Write(icnPingReply(buf[:k], n.cID, n.cRemote))
|
||||
case 0x00: // idle keepalive from the rig — nothing to do
|
||||
case 0x01: // retransmit request — resend from the CONTROL sent-buffer
|
||||
if k >= 8 {
|
||||
n.ctrlResend(icnLE.Uint16(buf[6:]))
|
||||
}
|
||||
case 0x05: // rig-initiated disconnect — it dropped US
|
||||
debugLog.Printf("icom net: rig sent DISCONNECT on control stream — session dropped by the rig")
|
||||
default:
|
||||
// Anything else on the control stream is (almost always) the rig's
|
||||
// reply to our token renewal. Log it: a 0x40-length token packet
|
||||
// carries a result code, and if the rig is REJECTING renewals this is
|
||||
// where the ~2-3 min disconnect originates. The hex makes the cause
|
||||
// visible in the friend's log without a protocol analyzer.
|
||||
if k >= 0x18 {
|
||||
debugLog.Printf("icom net: control reply len=%d head=% X", k, buf[:0x18])
|
||||
} else {
|
||||
debugLog.Printf("icom net: control reply len=%d head=% X", k, buf[:k])
|
||||
}
|
||||
}
|
||||
}
|
||||
if time.Since(lastIdle) > 100*time.Millisecond {
|
||||
_, _ = n.ctrl.Write(icnCtrl(0x00, 0, n.cID, n.cRemote))
|
||||
lastIdle = time.Now()
|
||||
}
|
||||
if time.Since(lastToken) > 45*time.Second {
|
||||
// Renew well inside the rig's ~2-min token timeout. 30 s (was 45) leaves room
|
||||
// for one lost renewal + its retransmit before the token would lapse.
|
||||
if time.Since(lastToken) > 30*time.Second {
|
||||
n.renewToken()
|
||||
lastToken = time.Now()
|
||||
}
|
||||
|
||||
@@ -283,6 +283,7 @@ func (b *IcomSerial) ReadState() (RigState, error) {
|
||||
b.dspMu.Unlock()
|
||||
return s, nil
|
||||
}
|
||||
debugLog.Printf("icom net: control link went quiet (no rig packets for >6 s) → reconnecting. If this recurs every ~2-3 min, the rig is invalidating the session (token renewal rejected).")
|
||||
return RigState{}, err // control link dead → let the Manager reconnect
|
||||
}
|
||||
// USB (no liveness signal): the rig briefly stops answering CI-V while it
|
||||
|
||||
Reference in New Issue
Block a user