revert(icom): drop Wake-on-LAN — the deck does not honour it
Tried on the real IC-7760: the magic packet wakes nothing; Icom's own mechanism is the network-standby session plus the CI-V power-on, which OpsLog already does. The MAC store and the WOL sender go, and the changelog entry with them. The CI-V pump now says once per session that the client pings are armed — invisible pings read as absent pings.
This commit is contained in:
+20
-83
@@ -21,7 +21,6 @@ package cat
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
@@ -85,23 +84,6 @@ func NewIcomNet(host, user, pass string, civAddr int, digitalDefault string, aud
|
||||
tr, err := dialIcomNet(host, user, pass, "OpsLog", b.rigAddr, cancel, audioSink)
|
||||
if err == nil {
|
||||
lastNetConnect = time.Now()
|
||||
} else {
|
||||
// The deck did not answer — a 7760 switched OFF takes its LAN
|
||||
// server down entirely. Send Wake-on-LAN to the remembered MAC so
|
||||
// the NEXT attempt finds a server: the rig wakes into standby, the
|
||||
// session opens, and the console's ON button does the rest.
|
||||
icnMACMu.Lock()
|
||||
load := icnLoadMAC
|
||||
icnMACMu.Unlock()
|
||||
if load != nil {
|
||||
if mac := load(); mac != "" {
|
||||
if werr := icnWakeOnLAN(mac); werr != nil {
|
||||
debugLog.Printf("icom net: wake-on-LAN to %s failed: %v", mac, werr)
|
||||
} else {
|
||||
debugLog.Printf("icom net: deck unreachable — sent Wake-on-LAN to %s", mac)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return tr, err
|
||||
}
|
||||
@@ -426,6 +408,7 @@ func (n *icomNet) civPump() {
|
||||
// quiet for 10 s, say so ONCE, with the last read error — a socket error
|
||||
// and a rig that stopped talking are different repairs, and the 30 s
|
||||
// watchdog that follows cannot tell them apart from where it sits.
|
||||
debugLog.Printf("icom net: client pings armed on the CI-V stream (every 500 ms)")
|
||||
lastPkt := time.Now()
|
||||
lastPing := time.Now()
|
||||
lastData := time.Now() // CI-V payload packets (replies + transceive)
|
||||
@@ -775,11 +758,6 @@ func dialIcomNet(host, user, pass, compName string, rigAddr byte, cancel <-chan
|
||||
return nil, err
|
||||
}
|
||||
debugLog.Printf("icom net: conninfo sent (rig mac % X) — opening CI-V stream", rigMAC)
|
||||
icnMACMu.Lock()
|
||||
if icnSaveMAC != nil {
|
||||
icnSaveMAC(hex.EncodeToString(rigMAC))
|
||||
}
|
||||
icnMACMu.Unlock()
|
||||
civ, err := net.DialUDP("udp4", &net.UDPAddr{Port: 50002}, vraddr)
|
||||
if err != nil {
|
||||
_ = ctrl.Close()
|
||||
@@ -1045,66 +1023,6 @@ func (n *icomNet) TXAudioSender() (func([]byte) error, error) {
|
||||
return n.audio.SendTXChunk, nil
|
||||
}
|
||||
|
||||
// The rig's MAC, learned from the login exchange and REMEMBERED (the app
|
||||
// persists it via these hooks): a 7760 that is switched off takes its LAN
|
||||
// server down with it, and the only way back in is Wake-on-LAN — which needs
|
||||
// the MAC when nothing else is answering.
|
||||
var (
|
||||
icnMACMu sync.Mutex
|
||||
icnSaveMAC func(mac string)
|
||||
icnLoadMAC func() string
|
||||
)
|
||||
|
||||
// SetIcomMACStore installs the persistence hooks for the rig's MAC address.
|
||||
func SetIcomMACStore(save func(string), load func() string) {
|
||||
icnMACMu.Lock()
|
||||
icnSaveMAC, icnLoadMAC = save, load
|
||||
icnMACMu.Unlock()
|
||||
}
|
||||
|
||||
// icnWakeOnLAN broadcasts the magic packet for mac ("aabbccddeeff" hex) so a
|
||||
// rig whose LAN server sleeps with it can be brought back without a walk to
|
||||
// the shack. Errors are returned for the log only — WOL is fire-and-forget.
|
||||
func icnWakeOnLAN(mac string) error {
|
||||
raw, err := hex.DecodeString(mac)
|
||||
if err != nil || len(raw) != 6 {
|
||||
return fmt.Errorf("bad MAC %q", mac)
|
||||
}
|
||||
pkt := make([]byte, 6+16*6)
|
||||
for i := 0; i < 6; i++ {
|
||||
pkt[i] = 0xFF
|
||||
}
|
||||
for i := 0; i < 16; i++ {
|
||||
copy(pkt[6+i*6:], raw)
|
||||
}
|
||||
conn, err := net.Dial("udp4", "255.255.255.255:9")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer conn.Close()
|
||||
_, err = conn.Write(pkt)
|
||||
return err
|
||||
}
|
||||
|
||||
// icnPing builds a CLIENT ping request (wfview's ping_packet: 0x15 bytes,
|
||||
// type 0x07, reply=0, a monotonic time at 0x11). The rig answers each one —
|
||||
// and, decisively, treats them as the client's sign of life: wfview sends one
|
||||
// every 500 ms on every stream, and OpsLog, which only ever REPLIED to the
|
||||
// rig's pings, watched the IC-7760 stop serving CI-V data about a minute into
|
||||
// every session. Same socket answered, same transport alive: the rig had
|
||||
// simply concluded nobody was listening.
|
||||
func icnPing(seq uint16, sentid, rcvdid uint32, ms uint32) []byte {
|
||||
b := make([]byte, 0x15)
|
||||
icnLE.PutUint32(b[0:], 0x15)
|
||||
icnLE.PutUint16(b[4:], 0x07)
|
||||
icnLE.PutUint16(b[6:], seq)
|
||||
icnLE.PutUint32(b[8:], sentid)
|
||||
icnLE.PutUint32(b[12:], rcvdid)
|
||||
b[0x10] = 0x00
|
||||
icnLE.PutUint32(b[0x11:], ms)
|
||||
return b
|
||||
}
|
||||
|
||||
func icnOpenClose(seq uint16, sentid, rcvdid uint32, civSeq uint16, magic byte) []byte {
|
||||
b := make([]byte, 0x16)
|
||||
icnLE.PutUint32(b[0:], 0x16)
|
||||
@@ -1169,3 +1087,22 @@ func icnHandshakeProbe(p []byte) {
|
||||
}
|
||||
debugLog.Printf("icom net: handshake rx %d bytes: % X", len(p), p[:n])
|
||||
}
|
||||
|
||||
// icnPing builds a CLIENT ping request (wfview's ping_packet: 0x15 bytes,
|
||||
// type 0x07, reply=0, a monotonic time at 0x11). The rig answers each one —
|
||||
// and, decisively, treats them as the client's sign of life: wfview sends one
|
||||
// every 500 ms on every stream, and OpsLog, which only ever REPLIED to the
|
||||
// rig's pings, watched the IC-7760 stop serving CI-V data about a minute into
|
||||
// every session. Same socket answered, same transport alive: the rig had
|
||||
// simply concluded nobody was listening.
|
||||
func icnPing(seq uint16, sentid, rcvdid uint32, ms uint32) []byte {
|
||||
b := make([]byte, 0x15)
|
||||
icnLE.PutUint32(b[0:], 0x15)
|
||||
icnLE.PutUint16(b[4:], 0x07)
|
||||
icnLE.PutUint16(b[6:], seq)
|
||||
icnLE.PutUint32(b[8:], sentid)
|
||||
icnLE.PutUint32(b[12:], rcvdid)
|
||||
b[0x10] = 0x00
|
||||
icnLE.PutUint32(b[0x11:], ms)
|
||||
return b
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user