Compare commits

..

5 Commits

Author SHA1 Message Date
Cameron Fleming 2badb0a3e9
Merge e177fdb1cd into 951173ba19 2025-02-17 10:33:50 +01:00
Cameron Fleming e177fdb1cd
Merge branch 'dev' into nevexo/display-brightness 2025-02-17 09:33:46 +00:00
Andrew 951173ba19
Restart mDNS every time the connection information changes (#155) 2025-02-13 18:10:47 +01:00
Cameron Fleming 2a99c2db9d
fix(net): stop dhcp client and release all v4 addr on linkdown (#16)
This commit fixes jetkvm/kvm#12 by disabling the udhcpc client when the
link goes down, it then removes all the active IPv4 addresses from the
deivce.

Once the link comes back up, it re-activates the udhcpc client so it can
fetch a new IPv4 address for the device.

This doesn't make any changes to the IPv6 side of things yet.
2025-02-13 15:41:10 +01:00
Cameron Fleming 0b5033f798
feat: restore EDID on reboot (#34)
This commit adds the config entry "EdidString" and saves the EDID string
when it's modified via the RPC.

The EDID is restored when the jetkvm_native control socket connects
(usually at boot)

Signed-off-by: Cameron Fleming <cameron@nevexo.space>
2025-02-13 14:42:07 +01:00
4 changed files with 78 additions and 5 deletions

View File

@ -22,7 +22,8 @@ type Config struct {
LocalAuthToken string `json:"local_auth_token"`
LocalAuthMode string `json:"localAuthMode"` //TODO: fix it with migration
WakeOnLanDevices []WakeOnLanDevice `json:"wake_on_lan_devices"`
DisplayMaxBrightness int `json:"display_max_brightness"`
EdidString string `json:"hdmi_edid_string"`
DisplayMaxBrightness int `json:"display_max_brightness"`
DisplayDimAfterSec int `json:"display_dim_after_sec"`
DisplayOffAfterSec int `json:"display_off_after_sec"`
}

View File

@ -189,6 +189,12 @@ func rpcSetEDID(edid string) error {
if err != nil {
return err
}
// Save EDID to config, allowing it to be restored on reboot.
LoadConfig()
config.EdidString = edid
SaveConfig()
return nil
}

View File

@ -152,6 +152,9 @@ func handleCtrlClient(conn net.Conn) {
ctrlSocketConn = conn
// Restore HDMI EDID if applicable
go restoreHdmiEdid()
readBuf := make([]byte, 4096)
for {
n, err := conn.Read(readBuf)
@ -304,3 +307,16 @@ func ensureBinaryUpdated(destPath string) error {
return nil
}
// Restore the HDMI EDID value from the config.
// Called after successful connection to jetkvm_native.
func restoreHdmiEdid() {
LoadConfig()
if config.EdidString != "" {
logger.Infof("Restoring HDMI EDID to %v", config.EdidString)
_, err := CallCtrlAction("set_edid", map[string]interface{}{"edid": config.EdidString})
if err != nil {
logger.Errorf("Failed to restore HDMI EDID: %v", err)
}
}
}

View File

@ -6,12 +6,15 @@ import (
"golang.org/x/net/ipv4"
"golang.org/x/net/ipv6"
"net"
"os/exec"
"time"
"github.com/vishvananda/netlink"
"github.com/vishvananda/netlink/nl"
)
var mDNSConn *mdns.Conn
var networkState struct {
Up bool
IPv4 string
@ -25,6 +28,23 @@ type LocalIpInfo struct {
MAC string
}
// setDhcpClientState sends signals to udhcpc to change it's current mode
// of operation. Setting active to true will force udhcpc to renew the DHCP lease.
// Setting active to false will put udhcpc into idle mode.
func setDhcpClientState(active bool) {
var signal string;
if active {
signal = "-SIGUSR1"
} else {
signal = "-SIGUSR2"
}
cmd := exec.Command("/usr/bin/killall", signal, "udhcpc");
if err := cmd.Run(); err != nil {
fmt.Printf("network: setDhcpClientState: failed to change udhcpc state: %s\n", err)
}
}
func checkNetworkState() {
iface, err := netlink.LinkByName("eth0")
if err != nil {
@ -47,22 +67,52 @@ func checkNetworkState() {
fmt.Printf("failed to get addresses for eth0: %v\n", err)
}
// If the link is going down, put udhcpc into idle mode.
// If the link is coming back up, activate udhcpc and force it to renew the lease.
if newState.Up != networkState.Up {
setDhcpClientState(newState.Up)
}
for _, addr := range addrs {
if addr.IP.To4() != nil {
newState.IPv4 = addr.IP.String()
if !newState.Up && networkState.Up {
// If the network is going down, remove all IPv4 addresses from the interface.
fmt.Printf("network: state transitioned to down, removing IPv4 address %s\n", addr.IP.String())
err := netlink.AddrDel(iface, &addr)
if err != nil {
fmt.Printf("network: failed to delete %s", addr.IP.String())
}
newState.IPv4 = "..."
} else {
newState.IPv4 = addr.IP.String()
}
} else if addr.IP.To16() != nil && newState.IPv6 == "" {
newState.IPv6 = addr.IP.String()
}
}
if newState != networkState {
networkState = newState
fmt.Println("network state changed")
//restart MDNS
startMDNS()
networkState = newState
requestDisplayUpdate()
}
}
func startMDNS() error {
//If server was previously running, stop it
if mDNSConn != nil {
fmt.Printf("Stopping mDNS server\n")
err := mDNSConn.Close()
if err != nil {
fmt.Printf("failed to stop mDNS server: %v\n", err)
}
}
//Start a new server
fmt.Printf("Starting mDNS server on jetkvm.local\n")
addr4, err := net.ResolveUDPAddr("udp4", mdns.DefaultAddressIPv4)
if err != nil {
return err
@ -83,10 +133,11 @@ func startMDNS() error {
return err
}
_, err = mdns.Server(ipv4.NewPacketConn(l4), ipv6.NewPacketConn(l6), &mdns.Config{
mDNSConn, err = mdns.Server(ipv4.NewPacketConn(l4), ipv6.NewPacketConn(l6), &mdns.Config{
LocalNames: []string{"jetkvm.local"}, //TODO: make it configurable
})
if err != nil {
mDNSConn = nil
return err
}
//defer server.Close()
@ -122,7 +173,6 @@ func init() {
}
}
}()
fmt.Println("Starting mDNS server")
err := startMDNS()
if err != nil {
fmt.Println("failed to run mDNS: %v", err)