From d0df8eaa44154b7ebfe4dc40546a9e89f39a84b4 Mon Sep 17 00:00:00 2001 From: Siyuan Miao Date: Wed, 24 Sep 2025 21:05:05 +0000 Subject: [PATCH] remove lldp --- internal/lldp/afpacket.go | 84 --- internal/lldp/afpacket_arm.go | 15 - internal/lldp/afpacket_nonarm.go | 15 - internal/lldp/lldp.go | 106 --- internal/lldp/neigh.go | 57 -- internal/lldp/rx.go | 264 ------- internal/native/eez/jetkvm.eez-project | 645 +++++++++++++++++- .../native/eez/jetkvm.eez-project-ui-state | 247 ++++--- internal/native/eez/src/ui/actions.c | 2 +- internal/native/eez/src/ui/actions.h | 1 + internal/native/eez/src/ui/screens.c | 184 +++++ internal/native/eez/src/ui/screens.h | 11 + internal/network/lldp.go | 46 -- internal/network/netif.go | 23 - jsonrpc.go | 1 - network.go | 5 - 16 files changed, 1004 insertions(+), 702 deletions(-) delete mode 100644 internal/lldp/afpacket.go delete mode 100644 internal/lldp/afpacket_arm.go delete mode 100644 internal/lldp/afpacket_nonarm.go delete mode 100644 internal/lldp/lldp.go delete mode 100644 internal/lldp/neigh.go delete mode 100644 internal/lldp/rx.go delete mode 100644 internal/network/lldp.go diff --git a/internal/lldp/afpacket.go b/internal/lldp/afpacket.go deleted file mode 100644 index 10775dda..00000000 --- a/internal/lldp/afpacket.go +++ /dev/null @@ -1,84 +0,0 @@ -package lldp - -import ( - "fmt" - "net" - "os" - "syscall" - "unsafe" - - "github.com/google/gopacket/afpacket" - "golang.org/x/sys/unix" -) - -const ( - afPacketBufferSize = 2 // in MiB - afPacketSnaplen = 9216 -) - -func afPacketComputeSize(targetSizeMb int, snaplen int, pageSize int) ( - frameSize int, blockSize int, numBlocks int, err error) { - if snaplen < pageSize { - frameSize = pageSize / (pageSize / snaplen) - } else { - frameSize = (snaplen/pageSize + 1) * pageSize - } - - // 128 is the default from the gopacket library so just use that - blockSize = frameSize * 128 - numBlocks = (targetSizeMb * 1024 * 1024) / blockSize - - if numBlocks == 0 { - return 0, 0, 0, fmt.Errorf("interface buffersize is too small") - } - - return frameSize, blockSize, numBlocks, nil -} - -func afPacketNewTPacket(ifName string) (*afpacket.TPacket, error) { - szFrame, szBlock, numBlocks, err := afPacketComputeSize( - afPacketBufferSize, - afPacketSnaplen, - os.Getpagesize()) - if err != nil { - return nil, err - } - - return afpacket.NewTPacket( - afpacket.OptInterface(ifName), - afpacket.OptFrameSize(szFrame), - afpacket.OptBlockSize(szBlock), - afpacket.OptNumBlocks(numBlocks), - afpacket.OptAddVLANHeader(false), - afpacket.SocketRaw, - afpacket.TPacketVersion3) -} - -type ifreq struct { - ifrName [IFNAMSIZ]byte - ifrHwaddr syscall.RawSockaddr -} - -func addMulticastAddr(ifName string, addr net.HardwareAddr) error { - fd, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, 0) - if err != nil { - return err - } - defer syscall.Close(fd) - - var name [IFNAMSIZ]byte - copy(name[:], []byte(ifName)) - - ifr := &ifreq{ - ifrName: name, - ifrHwaddr: toRawSockaddr(addr), - } - - _, _, ep := unix.Syscall(unix.SYS_IOCTL, uintptr(fd), - unix.SIOCADDMULTI, uintptr(unsafe.Pointer(ifr))) - - if ep != 0 { - return syscall.Errno(ep) - } - return nil -} diff --git a/internal/lldp/afpacket_arm.go b/internal/lldp/afpacket_arm.go deleted file mode 100644 index 470d571c..00000000 --- a/internal/lldp/afpacket_arm.go +++ /dev/null @@ -1,15 +0,0 @@ -//go:build arm && linux - -package lldp - -import ( - "net" - "syscall" -) - -func toRawSockaddr(mac net.HardwareAddr) (sockaddr syscall.RawSockaddr) { - for i, n := range mac { - sockaddr.Data[i] = uint8(n) - } - return -} diff --git a/internal/lldp/afpacket_nonarm.go b/internal/lldp/afpacket_nonarm.go deleted file mode 100644 index 2f11c823..00000000 --- a/internal/lldp/afpacket_nonarm.go +++ /dev/null @@ -1,15 +0,0 @@ -//go:build !arm && linux - -package lldp - -import ( - "net" - "syscall" -) - -func toRawSockaddr(mac net.HardwareAddr) (sockaddr syscall.RawSockaddr) { - for i, n := range mac { - sockaddr.Data[i] = int8(n) - } - return -} diff --git a/internal/lldp/lldp.go b/internal/lldp/lldp.go deleted file mode 100644 index 85020b6e..00000000 --- a/internal/lldp/lldp.go +++ /dev/null @@ -1,106 +0,0 @@ -package lldp - -import ( - "context" - "sync" - "time" - - "github.com/google/gopacket" - "github.com/google/gopacket/afpacket" - "github.com/jellydator/ttlcache/v3" - "github.com/jetkvm/kvm/internal/logging" - "github.com/rs/zerolog" -) - -var defaultLogger = logging.GetSubsystemLogger("lldp") - -type LLDP struct { - l *zerolog.Logger - tPacket *afpacket.TPacket - pktSource *gopacket.PacketSource - rxCtx context.Context - rxCancel context.CancelFunc - rxLock sync.Mutex - - enableRx bool - enableTx bool - - packets chan gopacket.Packet - interfaceName string - stop chan struct{} - - neighbors *ttlcache.Cache[string, Neighbor] -} - -type LLDPOptions struct { - InterfaceName string - EnableRx bool - EnableTx bool - Logger *zerolog.Logger -} - -func NewLLDP(opts *LLDPOptions) *LLDP { - if opts.Logger == nil { - opts.Logger = defaultLogger - } - - if opts.InterfaceName == "" { - opts.Logger.Fatal().Msg("InterfaceName is required") - } - - return &LLDP{ - interfaceName: opts.InterfaceName, - enableRx: opts.EnableRx, - enableTx: opts.EnableTx, - l: opts.Logger, - neighbors: ttlcache.New(ttlcache.WithTTL[string, Neighbor](1 * time.Hour)), - } -} - -func (l *LLDP) Start() error { - l.rxLock.Lock() - defer l.rxLock.Unlock() - - if l.rxCtx != nil { - l.l.Info().Msg("LLDP already started") - return nil - } - - l.rxCtx, l.rxCancel = context.WithCancel(context.Background()) - - if l.enableRx { - l.l.Info().Msg("setting up AF_PACKET") - if err := l.setUpCapture(); err != nil { - l.l.Error().Err(err).Msg("unable to set up AF_PACKET") - return err - } - if err := l.startCapture(); err != nil { - l.l.Error().Err(err).Msg("unable to start capture") - return err - } - } - - go l.neighbors.Start() - - return nil -} - -func (l *LLDP) Stop() error { - l.rxLock.Lock() - defer l.rxLock.Unlock() - - if l.rxCancel != nil { - l.rxCancel() - l.rxCancel = nil - l.rxCtx = nil - } - - if l.enableRx { - _ = l.shutdownCapture() - } - - l.neighbors.Stop() - l.neighbors.DeleteAll() - - return nil -} diff --git a/internal/lldp/neigh.go b/internal/lldp/neigh.go deleted file mode 100644 index f144238a..00000000 --- a/internal/lldp/neigh.go +++ /dev/null @@ -1,57 +0,0 @@ -package lldp - -import "time" - -type Neighbor struct { - Mac string `json:"mac"` - Source string `json:"source"` - ChassisID string `json:"chassis_id"` - PortID string `json:"port_id"` - PortDescription string `json:"port_description"` - SystemName string `json:"system_name"` - SystemDescription string `json:"system_description"` - TTL uint16 `json:"ttl"` - ManagementAddress string `json:"management_address"` - Values map[string]string `json:"values"` -} - -func (l *LLDP) addNeighbor(mac string, neighbor Neighbor, ttl time.Duration) { - logger := l.l.With(). - Str("mac", mac). - Interface("neighbor", neighbor). - Logger() - - current_neigh := l.neighbors.Get(mac) - if current_neigh != nil { - current_source := current_neigh.Value().Source - if current_source == "lldp" && neighbor.Source != "lldp" { - logger.Info().Msg("skip updating neighbor, as LLDP has higher priority") - return - } - } - - logger.Info().Msg("adding neighbor") - l.neighbors.Set(mac, neighbor, ttl) -} - -func (l *LLDP) deleteNeighbor(mac string) { - logger := l.l.With(). - Str("mac", mac). - Logger() - - logger.Info().Msg("deleting neighbor") - l.neighbors.Delete(mac) -} - -func (l *LLDP) GetNeighbors() []Neighbor { - items := l.neighbors.Items() - neighbors := make([]Neighbor, 0, len(items)) - - for _, item := range items { - neighbors = append(neighbors, item.Value()) - } - - l.l.Info().Interface("neighbors", neighbors).Msg("neighbors") - - return neighbors -} diff --git a/internal/lldp/rx.go b/internal/lldp/rx.go deleted file mode 100644 index 759d3ba6..00000000 --- a/internal/lldp/rx.go +++ /dev/null @@ -1,264 +0,0 @@ -package lldp - -import ( - "fmt" - "net" - "time" - - "github.com/google/gopacket" - "github.com/google/gopacket/layers" - "github.com/rs/zerolog" - "golang.org/x/net/bpf" -) - -const IFNAMSIZ = 16 - -var ( - lldpDefaultTTL = 120 * time.Second - cdpDefaultTTL = 180 * time.Second -) - -// from lldpd -// https://github.com/lldpd/lldpd/blob/9034c9332cca0c8b1a20e1287f0e5fed81f7eb2a/src/daemon/lldpd.h#L246 -// -//nolint:govet -var bpfFilter = []bpf.RawInstruction{ - {0x30, 0, 0, 0x00000000}, {0x54, 0, 0, 0x00000001}, {0x15, 0, 16, 0x00000001}, - {0x28, 0, 0, 0x0000000c}, {0x15, 0, 6, 0x000088cc}, - {0x20, 0, 0, 0x00000002}, {0x15, 2, 0, 0xc200000e}, - {0x15, 1, 0, 0xc2000003}, {0x15, 0, 2, 0xc2000000}, - {0x28, 0, 0, 0x00000000}, {0x15, 12, 13, 0x00000180}, - {0x20, 0, 0, 0x00000002}, {0x15, 0, 2, 0x52cccccc}, - {0x28, 0, 0, 0x00000000}, {0x15, 8, 9, 0x000001e0}, - {0x15, 1, 0, 0x0ccccccc}, {0x15, 0, 2, 0x81000100}, - {0x28, 0, 0, 0x00000000}, {0x15, 4, 5, 0x00000100}, - {0x20, 0, 0, 0x00000002}, {0x15, 0, 3, 0x2b000000}, - {0x28, 0, 0, 0x00000000}, {0x15, 0, 1, 0x000000e0}, - {0x6, 0, 0, 0x00040000}, - {0x6, 0, 0, 0x00000000}, -} - -var multicastAddrs = []string{ - // LLDP - "01:80:C2:00:00:00", - "01:80:C2:00:00:03", - "01:80:C2:00:00:0E", - // CDP - "01:00:0C:CC:CC:CC", -} - -func (l *LLDP) setUpCapture() error { - logger := l.l.With().Str("interface", l.interfaceName).Logger() - tPacket, err := afPacketNewTPacket(l.interfaceName) - if err != nil { - return err - } - logger.Info().Msg("created TPacket") - - // set up multicast addresses - // otherwise the kernel might discard the packets - // another workaround would be to enable promiscuous mode but that's too tricky - for _, mac := range multicastAddrs { - hwAddr, err := net.ParseMAC(mac) - if err != nil { - logger.Error().Msgf("unable to parse MAC address %s: %s", mac, err) - continue - } - - if err := addMulticastAddr(l.interfaceName, hwAddr); err != nil { - logger.Error().Msgf("unable to add multicast address %s: %s", mac, err) - continue - } - - logger.Info(). - Interface("hwaddr", hwAddr). - Msgf("added multicast address") - } - - if err = tPacket.SetBPF(bpfFilter); err != nil { - logger.Error().Msgf("unable to set BPF filter: %s", err) - tPacket.Close() - return err - } - logger.Info().Msg("BPF filter set") - - l.pktSource = gopacket.NewPacketSource(tPacket, layers.LayerTypeEthernet) - l.tPacket = tPacket - - return nil -} - -func (l *LLDP) startCapture() error { - logger := l.l.With().Str("interface", l.interfaceName).Logger() - if l.tPacket == nil { - return fmt.Errorf("AFPacket not initialized") - } - - if l.pktSource == nil { - return fmt.Errorf("packet source not initialized") - } - - go func() { - logger.Info().Msg("starting capture LLDP ethernet frames") - - for { - select { - case <-l.rxCtx.Done(): - logger.Info().Msg("shutting down LLDP capture") - return - case packet := <-l.pktSource.Packets(): - if err := l.handlePacket(packet, &logger); err != nil { - logger.Error().Msgf("error handling packet: %s", err) - } - } - } - }() - - return nil -} - -func (l *LLDP) handlePacket(packet gopacket.Packet, logger *zerolog.Logger) error { - linkLayer := packet.LinkLayer() - if linkLayer == nil { - return fmt.Errorf("no link layer") - } - - srcMac := linkLayer.LinkFlow().Src().String() - dstMac := linkLayer.LinkFlow().Dst().String() - - logger.Trace(). - Str("src_mac", srcMac). - Str("dst_mac", dstMac). - Int("length", len(packet.Data())). - Hex("data", packet.Data()). - Msg("received packet") - - lldpRaw := packet.Layer(layers.LayerTypeLinkLayerDiscovery) - if lldpRaw != nil { - logger.Trace().Msgf("Found LLDP Frame") - - lldpInfo := packet.Layer(layers.LayerTypeLinkLayerDiscoveryInfo) - if lldpInfo == nil { - return fmt.Errorf("no LLDP info layer") - } - - return l.handlePacketLLDP( - srcMac, - lldpRaw.(*layers.LinkLayerDiscovery), - lldpInfo.(*layers.LinkLayerDiscoveryInfo), - ) - } - - cdpRaw := packet.Layer(layers.LayerTypeCiscoDiscovery) - if cdpRaw != nil { - logger.Trace().Msgf("Found CDP Frame") - - cdpInfo := packet.Layer(layers.LayerTypeCiscoDiscoveryInfo) - if cdpInfo == nil { - return fmt.Errorf("no CDP info layer") - } - - return l.handlePacketCDP( - srcMac, - cdpRaw.(*layers.CiscoDiscovery), - cdpInfo.(*layers.CiscoDiscoveryInfo), - ) - } - - return nil -} - -func (l *LLDP) handlePacketLLDP(mac string, raw *layers.LinkLayerDiscovery, info *layers.LinkLayerDiscoveryInfo) error { - n := &Neighbor{ - Values: make(map[string]string), - Source: "lldp", - Mac: mac, - } - gotEnd := false - - ttl := lldpDefaultTTL - - for _, v := range raw.Values { - switch v.Type { - case layers.LLDPTLVEnd: - gotEnd = true - case layers.LLDPTLVChassisID: - n.ChassisID = string(raw.ChassisID.ID) - n.Values["chassis_id"] = n.ChassisID - case layers.LLDPTLVPortID: - n.PortID = string(raw.PortID.ID) - n.Values["port_id"] = n.PortID - case layers.LLDPTLVPortDescription: - n.PortDescription = info.PortDescription - n.Values["port_description"] = n.PortDescription - case layers.LLDPTLVSysName: - n.SystemName = info.SysName - n.Values["system_name"] = n.SystemName - case layers.LLDPTLVSysDescription: - n.SystemDescription = info.SysDescription - n.Values["system_description"] = n.SystemDescription - case layers.LLDPTLVMgmtAddress: - // n.ManagementAddress = info.MgmtAddress.Address - case layers.LLDPTLVTTL: - n.TTL = uint16(raw.TTL) - ttl = time.Duration(n.TTL) * time.Second - n.Values["ttl"] = fmt.Sprintf("%d", n.TTL) - case layers.LLDPTLVOrgSpecific: - for _, org := range info.OrgTLVs { - n.Values[fmt.Sprintf("org_specific_%d", org.OUI)] = string(org.Info) - } - } - } - - if gotEnd || ttl < 1*time.Second { - l.deleteNeighbor(mac) - } else { - l.addNeighbor(mac, *n, ttl) - } - - return nil -} - -func (l *LLDP) handlePacketCDP(mac string, raw *layers.CiscoDiscovery, info *layers.CiscoDiscoveryInfo) error { - // TODO: implement full CDP parsing - n := &Neighbor{ - Values: make(map[string]string), - Source: "cdp", - Mac: mac, - } - - ttl := cdpDefaultTTL - - n.ChassisID = info.DeviceID - n.PortID = info.PortID - n.SystemName = info.SysName - n.SystemDescription = info.Platform - n.TTL = uint16(raw.TTL) - - if n.TTL > 1 { - ttl = time.Duration(n.TTL) * time.Second - } - - if len(info.MgmtAddresses) > 0 { - n.ManagementAddress = string(info.MgmtAddresses[0]) - } - - l.addNeighbor(mac, *n, ttl) - - return nil -} - -func (l *LLDP) shutdownCapture() error { - if l.tPacket != nil { - l.l.Info().Msg("closing TPacket") - l.tPacket.Close() - l.tPacket = nil - } - - if l.pktSource != nil { - l.l.Info().Msg("closing packet source") - l.pktSource = nil - } - - return nil -} diff --git a/internal/native/eez/jetkvm.eez-project b/internal/native/eez/jetkvm.eez-project index 036b2b1c..465cdea9 100644 --- a/internal/native/eez/jetkvm.eez-project +++ b/internal/native/eez/jetkvm.eez-project @@ -48,7 +48,7 @@ { "objID": "58af3ebb-96b3-494c-f4e3-9c23852e3e42", "fileName": "actions.c", - "template": "#include \"actions.h\"\n#include \"screens.h\"\n\nint handle_gesture_screen_switch(lv_event_t *e, lv_dir_t direction, int screenId) {\n lv_event_code_t event_code = lv_event_get_code(e);\n if (event_code != LV_EVENT_GESTURE) {\n return 0;\n }\n\n if (lv_indev_get_gesture_dir(lv_indev_get_act()) != direction) {\n return 0;\n }\n lv_indev_wait_release(lv_indev_get_act());\n loadScreen(screenId);\n return 1;\n}\n\nvoid action_switch_to_menu(lv_event_t *e) {\n loadScreen(SCREEN_ID_MENU_SCREEN);\n}\n\nvoid action_switch_to_advanced_menu(lv_event_t *e) {\n loadScreen(SCREEN_ID_MENU_ADVANCED_SCREEN);\n}\n\nvoid action_switch_to_status(lv_event_t *e) {\n loadScreen(SCREEN_ID_STATUS_SCREEN);\n}\n\nvoid action_switch_to_about(lv_event_t *e) {\n loadScreen(SCREEN_ID_ABOUT_SCREEN);\n}\n\nvoid action_menu_screen_gesture(lv_event_t * e) {\n handle_gesture_screen_switch(e, LV_DIR_RIGHT, SCREEN_ID_HOME_SCREEN);\n}\n\nvoid action_menu_advanced_screen_gesture(lv_event_t * e) {\n handle_gesture_screen_switch(e, LV_DIR_RIGHT, SCREEN_ID_MENU_SCREEN);\n}\n\nvoid action_reset_config_screen_gesture(lv_event_t * e) {\n handle_gesture_screen_switch(e, LV_DIR_RIGHT, SCREEN_ID_MENU_ADVANCED_SCREEN);\n}\n\nvoid action_home_screen_gesture(lv_event_t * e) {\n handle_gesture_screen_switch(e, LV_DIR_LEFT, SCREEN_ID_MENU_SCREEN);\n}\n\nvoid action_about_screen_gesture(lv_event_t * e) {\n handle_gesture_screen_switch(e, LV_DIR_RIGHT, SCREEN_ID_MENU_SCREEN);\n}" + "template": "#include \"actions.h\"\n#include \"screens.h\"\n\nint handle_gesture_screen_switch(lv_event_t *e, lv_dir_t direction, int screenId) {\n lv_event_code_t event_code = lv_event_get_code(e);\n if (event_code != LV_EVENT_GESTURE) {\n return 0;\n }\n\n if (lv_indev_get_gesture_dir(lv_indev_get_act()) != direction) {\n return 0;\n }\n lv_indev_wait_release(lv_indev_get_act());\n loadScreen(screenId);\n return 1;\n}\n\nvoid action_switch_to_menu(lv_event_t *e) {\n loadScreen(SCREEN_ID_MENU_SCREEN);\n}\n\nvoid action_switch_to_advanced_menu(lv_event_t *e) {\n loadScreen(SCREEN_ID_MENU_ADVANCED_SCREEN);\n}\n\nvoid action_switch_to_status(lv_event_t *e) {\n loadScreen(SCREEN_ID_STATUS_SCREEN);\n}\n\nvoid action_switch_to_about(lv_event_t *e) {\n loadScreen(SCREEN_ID_ABOUT_SCREEN);\n}\n\nvoid action_menu_screen_gesture(lv_event_t * e) {\n handle_gesture_screen_switch(e, LV_DIR_RIGHT, SCREEN_ID_HOME_SCREEN);\n}\n\nvoid action_menu_advanced_screen_gesture(lv_event_t * e) {\n handle_gesture_screen_switch(e, LV_DIR_RIGHT, SCREEN_ID_MENU_SCREEN);\n}\n\nvoid action_reset_config_screen_gesture(lv_event_t * e) {\n handle_gesture_screen_switch(e, LV_DIR_RIGHT, SCREEN_ID_MENU_SCREEN);\n}\n\nvoid action_home_screen_gesture(lv_event_t * e) {\n handle_gesture_screen_switch(e, LV_DIR_LEFT, SCREEN_ID_MENU_SCREEN);\n}\n\nvoid action_about_screen_gesture(lv_event_t * e) {\n handle_gesture_screen_switch(e, LV_DIR_RIGHT, SCREEN_ID_MENU_SCREEN);\n}" }, { "objID": "1dbd1b7e-7270-47f0-ee02-e80bdae287cf", @@ -233,6 +233,14 @@ "localVariables": [], "userProperties": [], "name": "HandleCommonPressEvent" + }, + { + "objID": "74dd35a7-73c0-4ab8-b02a-2c2b4ea411c8", + "components": [], + "connectionLines": [], + "localVariables": [], + "userProperties": [], + "name": "ResetConfig" } ], "userPages": [ @@ -6370,6 +6378,641 @@ "isUsedAsUserWidget": false, "createAtStart": true, "deleteOnScreenUnload": false + }, + { + "objID": "75ea84f5-a80e-419b-93b4-7153c186ade8", + "components": [ + { + "objID": "80031032-9691-4aa9-c498-df60ab57c4b2", + "type": "LVGLScreenWidget", + "left": 0, + "top": 0, + "width": 300, + "height": 240, + "customInputs": [], + "customOutputs": [], + "style": { + "objID": "1619ccde-3843-4871-e9fa-8f0117af2488", + "useStyle": "default", + "conditionalStyles": [], + "childStyles": [] + }, + "timeline": [], + "eventHandlers": [ + { + "objID": "28455dcc-0b2c-4a91-f778-fb0ea3610860", + "eventName": "GESTURE", + "handlerType": "action", + "action": "AboutScreenGesture", + "userData": 0 + } + ], + "leftUnit": "px", + "topUnit": "px", + "widthUnit": "px", + "heightUnit": "px", + "children": [ + { + "objID": "4fb18b2d-7616-4853-d070-6e195e06ece5", + "type": "LVGLContainerWidget", + "left": 0, + "top": 0, + "width": 100, + "height": 100, + "customInputs": [], + "customOutputs": [], + "style": { + "objID": "33aa8677-8ad3-4ab1-c6d3-994af54238b3", + "useStyle": "default", + "conditionalStyles": [], + "childStyles": [] + }, + "timeline": [], + "eventHandlers": [], + "identifier": "", + "leftUnit": "px", + "topUnit": "px", + "widthUnit": "%", + "heightUnit": "%", + "children": [ + { + "objID": "7db746f3-8899-43e3-c639-36be24c99641", + "type": "LVGLContainerWidget", + "left": 0, + "top": 0, + "width": 100, + "height": 32, + "customInputs": [], + "customOutputs": [], + "style": { + "objID": "1b33cd77-fd0c-4210-d97a-a1d1fa3d5b87", + "useStyle": "default", + "conditionalStyles": [], + "childStyles": [] + }, + "timeline": [], + "eventHandlers": [], + "identifier": "AboutHeaderContainer_1", + "leftUnit": "px", + "topUnit": "px", + "widthUnit": "%", + "heightUnit": "content", + "children": [ + { + "objID": "7b7ad394-ff9e-4a3b-bc57-835d9069a41a", + "type": "LVGLButtonWidget", + "left": 0, + "top": 0, + "width": 32, + "height": 32, + "customInputs": [], + "customOutputs": [], + "style": { + "objID": "ee403bac-e4be-4185-800e-c8ebfb43f0f8", + "useStyle": "default", + "conditionalStyles": [], + "childStyles": [] + }, + "timeline": [], + "eventHandlers": [ + { + "objID": "5f651ba7-340c-4481-c2ed-c6952ef753d7", + "eventName": "CLICKED", + "handlerType": "action", + "action": "SwitchToMenu", + "userData": 0 + } + ], + "leftUnit": "px", + "topUnit": "px", + "widthUnit": "px", + "heightUnit": "px", + "children": [ + { + "objID": "5158d230-b879-40e9-fb63-8a67d47c7f5a", + "type": "LVGLImageWidget", + "left": -1, + "top": 2, + "width": 8, + "height": 12, + "customInputs": [], + "customOutputs": [], + "style": { + "objID": "c6220349-2a7b-43b6-eeb3-e83b4c9f9830", + "useStyle": "default", + "conditionalStyles": [], + "childStyles": [] + }, + "timeline": [], + "eventHandlers": [], + "leftUnit": "px", + "topUnit": "px", + "widthUnit": "content", + "heightUnit": "content", + "children": [], + "widgetFlags": "ADV_HITTEST|CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLLABLE|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_WITH_ARROW|SNAPPABLE", + "hiddenFlagType": "literal", + "clickableFlagType": "literal", + "flagScrollbarMode": "", + "flagScrollDirection": "", + "scrollSnapX": "", + "scrollSnapY": "", + "checkedStateType": "literal", + "disabledStateType": "literal", + "states": "", + "localStyles": { + "objID": "2acf6cec-5cb1-48f5-fe9e-fb9f6b8a34dd" + }, + "group": "", + "groupIndex": 0, + "image": "back-caret", + "setPivot": false, + "pivotX": 0, + "pivotY": 0, + "zoom": 256, + "angle": 0, + "innerAlign": "CENTER" + } + ], + "widgetFlags": "CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_ON_FOCUS|SCROLL_WITH_ARROW|SNAPPABLE", + "hiddenFlagType": "literal", + "clickableFlag": true, + "clickableFlagType": "literal", + "flagScrollbarMode": "", + "flagScrollDirection": "", + "scrollSnapX": "", + "scrollSnapY": "", + "checkedStateType": "literal", + "disabledStateType": "literal", + "states": "", + "useStyle": "BackButton", + "localStyles": { + "objID": "aa905e79-a9f2-41a9-dfa6-ba7c9a9d07b7" + }, + "group": "", + "groupIndex": 0 + }, + { + "objID": "4bb0abba-9a53-40f1-9ba4-dc7ecae15005", + "type": "LVGLLabelWidget", + "left": 0, + "top": 0, + "width": 117, + "height": 20, + "customInputs": [], + "customOutputs": [], + "style": { + "objID": "883737b6-b175-4eb5-c072-95e67f7f140d", + "useStyle": "default", + "conditionalStyles": [], + "childStyles": [] + }, + "timeline": [], + "eventHandlers": [], + "identifier": "", + "leftUnit": "%", + "topUnit": "%", + "widthUnit": "content", + "heightUnit": "content", + "children": [], + "widgetFlags": "CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLLABLE|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_WITH_ARROW|SNAPPABLE", + "hiddenFlagType": "literal", + "clickableFlagType": "literal", + "checkedStateType": "literal", + "disabledStateType": "literal", + "states": "", + "useStyle": "HeaderLink", + "localStyles": { + "objID": "a7abc8b4-5ce5-4506-8ecb-e4a3d059e35c" + }, + "groupIndex": 0, + "text": "Reset Device", + "textType": "literal", + "longMode": "WRAP", + "recolor": false + } + ], + "widgetFlags": "CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLLABLE|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_WITH_ARROW|SNAPPABLE", + "hiddenFlagType": "literal", + "clickableFlag": true, + "clickableFlagType": "literal", + "flagScrollbarMode": "", + "flagScrollDirection": "", + "scrollSnapX": "", + "scrollSnapY": "", + "checkedStateType": "literal", + "disabledStateType": "literal", + "states": "", + "useStyle": "FlowRowSpaceBetween", + "localStyles": { + "objID": "71b261bf-896b-49ae-e6c8-5988ce9f2beb", + "definition": { + "MAIN": { + "DEFAULT": { + "pad_right": 4 + } + } + } + }, + "group": "", + "groupIndex": 0 + }, + { + "objID": "8730fe01-337a-4e8f-8767-1a4a9bd7ecf8", + "type": "LVGLContainerWidget", + "left": 0, + "top": 0, + "width": 100, + "height": 80, + "customInputs": [], + "customOutputs": [], + "style": { + "objID": "b5b7b2cf-88ec-40c5-a2d9-2de27b0be05f", + "useStyle": "default", + "conditionalStyles": [], + "childStyles": [] + }, + "timeline": [], + "eventHandlers": [], + "identifier": "AboutItemsContainer_1", + "leftUnit": "px", + "topUnit": "px", + "widthUnit": "%", + "heightUnit": "%", + "children": [ + { + "objID": "28edf722-8217-4ad1-834a-3df9a3c9beb6", + "type": "LVGLContainerWidget", + "left": 0, + "top": 0, + "width": 100, + "height": 118, + "customInputs": [], + "customOutputs": [], + "style": { + "objID": "bebac5ee-0e43-4f46-cb40-5250b4275680", + "useStyle": "default", + "conditionalStyles": [], + "childStyles": [] + }, + "timeline": [], + "eventHandlers": [], + "leftUnit": "px", + "topUnit": "px", + "widthUnit": "%", + "heightUnit": "content", + "children": [ + { + "objID": "d2955d4d-7acb-44d0-e221-9a458d569a3c", + "type": "LVGLContainerWidget", + "left": 0, + "top": 0, + "width": 100, + "height": 60, + "customInputs": [], + "customOutputs": [], + "style": { + "objID": "3745f1bf-b80b-4894-ef1d-3074a6b5f6f9", + "useStyle": "default", + "conditionalStyles": [], + "childStyles": [] + }, + "timeline": [], + "eventHandlers": [], + "identifier": "systemVersionContainer_1", + "leftUnit": "px", + "topUnit": "px", + "widthUnit": "%", + "heightUnit": "content", + "children": [ + { + "objID": "c18a5cbf-d0f7-45cd-d6f4-d26bb27b229a", + "type": "LVGLLabelWidget", + "left": 0, + "top": 0, + "width": 100, + "height": 40, + "customInputs": [], + "customOutputs": [], + "style": { + "objID": "06b4182d-0e0a-4b9b-d2fb-013a45b10d48", + "useStyle": "default", + "conditionalStyles": [], + "childStyles": [] + }, + "timeline": [], + "eventHandlers": [], + "identifier": "systemVersion_1", + "leftUnit": "px", + "topUnit": "px", + "widthUnit": "%", + "heightUnit": "content", + "children": [], + "widgetFlags": "CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLLABLE|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_WITH_ARROW|SNAPPABLE", + "hiddenFlagType": "literal", + "clickableFlagType": "literal", + "flagScrollbarMode": "", + "flagScrollDirection": "", + "scrollSnapX": "", + "scrollSnapY": "", + "checkedStateType": "literal", + "disabledStateType": "literal", + "states": "", + "useStyle": "InfoContentLabel", + "localStyles": { + "objID": "3adf240a-5ac9-4a43-e894-6204bded0ba8", + "definition": { + "MAIN": { + "DEFAULT": { + "text_font": "FontBook20" + } + } + } + }, + "group": "", + "groupIndex": 0, + "text": "Press and hold for\n20 seconds", + "textType": "literal", + "longMode": "WRAP", + "recolor": false, + "previewValue": "0.0.1" + } + ], + "widgetFlags": "CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_WITH_ARROW|SNAPPABLE", + "hiddenFlagType": "literal", + "clickableFlag": true, + "clickableFlagType": "literal", + "flagScrollbarMode": "", + "flagScrollDirection": "", + "scrollSnapX": "", + "scrollSnapY": "", + "checkedStateType": "literal", + "disabledStateType": "literal", + "states": "", + "useStyle": "FlexColumnStart", + "localStyles": { + "objID": "e3a2d4b4-9a5d-4789-cd9c-9b3145afe7c5", + "definition": { + "MAIN": { + "DEFAULT": { + "pad_right": 10, + "pad_left": 10, + "pad_top": 10, + "pad_bottom": 10 + } + } + } + }, + "group": "", + "groupIndex": 0 + }, + { + "objID": "e3c027f5-a51d-49ee-c7d6-74eca94fbf6a", + "type": "LVGLContainerWidget", + "left": 0, + "top": 0, + "width": 100, + "height": 50, + "customInputs": [], + "customOutputs": [], + "style": { + "objID": "c6616393-44b5-44c4-a7ba-2e7df5979370", + "useStyle": "default", + "conditionalStyles": [], + "childStyles": [] + }, + "timeline": [], + "eventHandlers": [], + "identifier": "appVersionContainer_1", + "leftUnit": "px", + "topUnit": "px", + "widthUnit": "%", + "heightUnit": "content", + "children": [ + { + "objID": "bf6a4dde-d627-4c38-9f0d-0d64b5740b1e", + "type": "LVGLButtonWidget", + "left": 0, + "top": 0, + "width": 100, + "height": 50, + "customInputs": [], + "customOutputs": [], + "style": { + "objID": "24a99368-5b88-43a0-fad7-586858d4ca9d", + "useStyle": "default", + "conditionalStyles": [], + "childStyles": [] + }, + "timeline": [], + "eventHandlers": [ + { + "objID": "ecf97e0e-553c-4f12-d07d-75b8641d9374", + "eventName": "LONG_PRESSED", + "handlerType": "action", + "action": "ResetConfig", + "userData": 0 + } + ], + "leftUnit": "px", + "topUnit": "px", + "widthUnit": "%", + "heightUnit": "px", + "children": [ + { + "objID": "77fdf48f-8ae9-42e3-fff3-0b5b790e4779", + "type": "LVGLLabelWidget", + "left": 0, + "top": 0, + "width": 94, + "height": 16, + "customInputs": [], + "customOutputs": [], + "style": { + "objID": "2be8e2df-6e92-48c8-9a9b-79a3fad47cd4", + "useStyle": "default", + "conditionalStyles": [], + "childStyles": [] + }, + "timeline": [], + "eventHandlers": [], + "leftUnit": "px", + "topUnit": "px", + "widthUnit": "content", + "heightUnit": "content", + "children": [], + "widgetFlags": "CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLLABLE|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_WITH_ARROW|SNAPPABLE", + "hiddenFlagType": "literal", + "clickableFlagType": "literal", + "flagScrollbarMode": "", + "flagScrollDirection": "", + "scrollSnapX": "", + "scrollSnapY": "", + "checkedStateType": "literal", + "disabledStateType": "literal", + "states": "", + "localStyles": { + "objID": "e6b35e61-3c43-403d-f7bc-57f559f0b0c6", + "definition": { + "MAIN": { + "DEFAULT": { + "align": "CENTER", + "text_align": "LEFT" + } + } + } + }, + "group": "", + "groupIndex": 0, + "text": "Hold to reset", + "textType": "literal", + "longMode": "WRAP", + "recolor": false + } + ], + "widgetFlags": "CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_ON_FOCUS|SCROLL_WITH_ARROW|SNAPPABLE", + "hiddenFlagType": "literal", + "clickableFlag": true, + "clickableFlagType": "literal", + "flagScrollbarMode": "", + "flagScrollDirection": "", + "scrollSnapX": "", + "scrollSnapY": "", + "checkedStateType": "literal", + "disabledStateType": "literal", + "states": "", + "useStyle": "", + "localStyles": { + "objID": "ae0e0a47-b565-4ed9-c58a-1d01bc4c6a64", + "definition": { + "MAIN": { + "DEFAULT": { + "bg_color": "DC2626", + "text_align": "LEFT", + "pad_right": 13 + } + } + } + }, + "group": "", + "groupIndex": 0 + } + ], + "widgetFlags": "CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_WITH_ARROW|SNAPPABLE", + "hiddenFlagType": "literal", + "clickableFlag": true, + "clickableFlagType": "literal", + "flagScrollbarMode": "", + "flagScrollDirection": "", + "scrollSnapX": "", + "scrollSnapY": "", + "checkedStateType": "literal", + "disabledStateType": "literal", + "states": "", + "useStyle": "FlexColumnStart", + "localStyles": { + "objID": "e3c2c8d3-f39f-4af9-c9b3-51281eaf3012" + }, + "group": "", + "groupIndex": 0 + } + ], + "widgetFlags": "CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_WITH_ARROW|SNAPPABLE", + "hiddenFlagType": "literal", + "clickableFlag": true, + "clickableFlagType": "literal", + "flagScrollbarMode": "", + "flagScrollDirection": "", + "scrollSnapX": "", + "scrollSnapY": "", + "checkedStateType": "literal", + "disabledStateType": "literal", + "states": "", + "useStyle": "FlexColumnStart", + "localStyles": { + "objID": "ab7c25b4-573b-4158-d642-49507e72b05e", + "definition": { + "MAIN": { + "DEFAULT": { + "pad_right": 10 + } + } + } + }, + "group": "", + "groupIndex": 0 + } + ], + "widgetFlags": "CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLL_CHAIN_VER|SNAPPABLE|SCROLL_ELASTIC|SCROLL_WITH_ARROW|SCROLL_MOMENTUM|SCROLL_CHAIN_HOR|SCROLLABLE", + "hiddenFlagType": "literal", + "clickableFlag": true, + "clickableFlagType": "literal", + "flagScrollbarMode": "auto", + "flagScrollDirection": "ver", + "scrollSnapX": "start", + "scrollSnapY": "", + "checkedStateType": "literal", + "disabledStateType": "literal", + "states": "", + "useStyle": "FlexColumnStart", + "localStyles": { + "objID": "ea6dd0a1-f5ea-49dc-c53a-e5e6ad5f7e38", + "definition": { + "MAIN": { + "DEFAULT": { + "pad_right": 4 + } + } + } + }, + "group": "", + "groupIndex": 0 + } + ], + "widgetFlags": "CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER|SCROLL_MOMENTUM|SCROLL_WITH_ARROW|SNAPPABLE|SCROLL_ELASTIC", + "hiddenFlagType": "literal", + "clickableFlag": true, + "clickableFlagType": "literal", + "flagScrollbarMode": "", + "flagScrollDirection": "", + "scrollSnapX": "", + "scrollSnapY": "", + "checkedStateType": "literal", + "disabledStateType": "literal", + "states": "", + "useStyle": "FlexStart", + "localStyles": { + "objID": "f8b4c1e4-75cd-41d0-d7ac-ae77f3bd041f" + }, + "group": "", + "groupIndex": 0 + } + ], + "widgetFlags": "CLICKABLE|PRESS_LOCK|CLICK_FOCUSABLE|GESTURE_BUBBLE|SNAPPABLE|SCROLLABLE|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER", + "hiddenFlagType": "literal", + "clickableFlag": true, + "clickableFlagType": "literal", + "checkedStateType": "literal", + "disabledStateType": "literal", + "states": "", + "useStyle": "FlexScreenMenu", + "localStyles": { + "objID": "d99a1659-8336-49a7-af47-8e80b522d52e" + }, + "groupIndex": 0 + } + ], + "connectionLines": [], + "localVariables": [], + "userProperties": [], + "name": "ResetConfigScreen", + "left": 0, + "top": 0, + "width": 300, + "height": 240, + "isUsedAsUserWidget": false, + "createAtStart": true, + "deleteOnScreenUnload": false } ], "userWidgets": [], diff --git a/internal/native/eez/jetkvm.eez-project-ui-state b/internal/native/eez/jetkvm.eez-project-ui-state index 177671b1..6685cef6 100644 --- a/internal/native/eez/jetkvm.eez-project-ui-state +++ b/internal/native/eez/jetkvm.eez-project-ui-state @@ -1,12 +1,12 @@ { "navigation": { - "selectedUserPageObject": "[jetkvm.eez-project]:/userPages/5", - "selectedActionObject": "[jetkvm.eez-project]:/actions/0", + "selectedUserPageObject": "[jetkvm.eez-project]:/userPages/8", + "selectedActionObject": "[jetkvm.eez-project]:/actions/5", "selectedGlobalVariableObject": "[jetkvm.eez-project]:/variables/globalVariables/1", - "selectedStyleObject": "[jetkvm.eez-project]:/lvglStyles/styles/0", + "selectedStyleObject": "[jetkvm.eez-project]:/lvglStyles/styles/8", "selectedThemeObject": "[jetkvm.eez-project]:/themes/0", "selectedFontObject": "[jetkvm.eez-project]:/fonts/4", - "selectedBitmapObject": "[jetkvm.eez-project]:/bitmaps/11", + "selectedBitmapObject": "[jetkvm.eez-project]:/bitmaps/9", "subnavigationSelectedItems": { "variables-tab/sub-navigation/selected-item": "Global" } @@ -30,7 +30,7 @@ { "type": "border", "selected": 2, - "size": 113.5, + "size": 296.5, "location": "right", "children": [ { @@ -77,7 +77,7 @@ }, { "type": "border", - "selected": 1, + "selected": 0, "location": "bottom", "children": [ { @@ -130,6 +130,7 @@ "type": "tabset", "id": "#2e3d9a08-c69c-42b5-b434-525109f2a5a7", "weight": 1, + "selected": 1, "enableClose": false, "children": [ { @@ -188,19 +189,40 @@ "enableClose": false, "icon": "svg:variable" } - ], - "active": true + ] } ] }, { "type": "tabset", "id": "EDITORS", - "weight": 49.31058517127421, - "selected": 4, + "weight": 56.255429602160085, + "selected": 2, "enableDeleteWhenEmpty": false, "enableClose": false, "children": [ + { + "type": "tab", + "id": "#4610a27a-ce31-4747-b3c0-488eafeb606b", + "name": "StatusScreen", + "component": "editor", + "config": { + "objectPath": "[jetkvm.eez-project]:/userPages/7", + "permanent": false + }, + "icon": "svg:page" + }, + { + "type": "tab", + "id": "#ef9d764d-e942-47f4-beec-136cbd40ffd7", + "name": "ResetConfigScreen", + "component": "editor", + "config": { + "objectPath": "[jetkvm.eez-project]:/userPages/8", + "permanent": true + }, + "icon": "svg:page" + }, { "type": "tab", "id": "#aec56ae8-5b75-4a2f-ad81-f0d7d683c77a", @@ -215,11 +237,11 @@ { "type": "tab", "id": "#c8dece00-e490-46b8-8a14-5dcfa8bbce36", - "name": "AboutScreen", + "name": "NoNetworkScreen", "component": "editor", "config": { - "objectPath": "[jetkvm.eez-project]:/userPages/5", - "permanent": false + "objectPath": "[jetkvm.eez-project]:/userPages/7", + "permanent": true }, "icon": "svg:page" }, @@ -257,12 +279,13 @@ }, "icon": "material:settings" } - ] + ], + "active": true }, { "type": "row", "id": "#ee319cf9-6145-49e4-b40e-1d999be897c8", - "weight": 24.95234430353635, + "weight": 18.007499872650474, "children": [ { "type": "tabset", @@ -1065,8 +1088,7 @@ "0": { "0": { "0": { - "1": {}, - "$selected": true + "1": {} } } } @@ -1086,11 +1108,58 @@ } }, "[jetkvm.eez-project]:/userPages/1[flow-state]": { + "selection": { + "0": { + "0": { + "0": {}, + "1": {}, + "$selected": true + } + } + }, + "transform": { + "translate": { + "x": -180, + "y": -207 + }, + "scale": 1 + }, + "timeline": { + "isEditorActive": false, + "position": 0, + "secondToPx": 200, + "scrollLeft": 0 + } + }, + "[jetkvm.eez-project]:/lvglStyles/styles[tree-state]": { + "0": {}, + "1": {}, + "2": {}, + "3": {}, + "4": { + "$selected": true + }, + "5": { + "$selected": true + }, + "6": { + "$selected": true + }, + "7": { + "$selected": true + }, + "8": { + "$selected": true + } + }, + "[jetkvm.eez-project]:/userPages/2[flow-state]": { "selection": { "0": { "0": { "0": { - "0": {}, + "0": { + "$selected": true + }, "1": { "0": {} } @@ -1102,9 +1171,7 @@ "3": { "0": { "0": {}, - "1": { - "$selected": true - } + "1": {} }, "1": { "0": {}, @@ -1128,12 +1195,7 @@ "scrollLeft": 0 } }, - "[jetkvm.eez-project]:/lvglStyles/styles[tree-state]": { - "0": { - "$selected": true - } - }, - "[jetkvm.eez-project]:/userPages/2[flow-state]": { + "[jetkvm.eez-project]:/userPages/3[flow-state]": { "selection": { "0": { "0": { @@ -1142,13 +1204,14 @@ }, "1": { "0": { - "0": {}, + "0": { + "$selected": true + }, "1": {}, "2": {}, "3": {}, "4": { - "0": {}, - "$selected": true + "0": {} } } } @@ -1169,39 +1232,6 @@ "scrollLeft": 0 } }, - "[jetkvm.eez-project]:/userPages/3[flow-state]": { - "selection": { - "0": { - "0": { - "0": { - "0": {}, - "$selected": true - }, - "1": { - "0": { - "0": {}, - "1": {}, - "2": {}, - "3": {} - } - } - } - } - }, - "transform": { - "translate": { - "x": -150, - "y": -120 - }, - "scale": 1 - }, - "timeline": { - "isEditorActive": false, - "position": 0, - "secondToPx": 200, - "scrollLeft": 0 - } - }, "[jetkvm.eez-project]:/userPages/4[flow-state]": { "selection": { "0": { @@ -1245,19 +1275,8 @@ "1": { "0": { "0": {}, - "1": { - "1": {} - }, - "2": {}, - "3": {}, - "4": {}, - "5": { - "1": { - "$selected": true - } - }, - "6": {}, - "7": {} + "1": {}, + "2": {} } } } @@ -1300,10 +1319,68 @@ "0": {}, "1": { "0": { - "0": {}, + "0": { + "1": {} + }, "2": { - "1": { - "$selected": true + "1": {} + } + } + } + } + } + }, + "transform": { + "translate": { + "x": -10.425644531250029, + "y": -122 + }, + "scale": 1 + }, + "timeline": { + "isEditorActive": false, + "position": 0, + "secondToPx": 200, + "scrollLeft": 0 + } + }, + "[jetkvm.eez-project]:/userPages/7[flow-state]": { + "selection": { + "0": { + "0": { + "0": {}, + "1": {}, + "$selected": true + } + } + }, + "transform": { + "translate": { + "x": -180, + "y": -207 + }, + "scale": 1 + }, + "timeline": { + "isEditorActive": false, + "position": 0, + "secondToPx": 200, + "scrollLeft": 0 + } + }, + "[jetkvm.eez-project]:/userPages/8[flow-state]": { + "selection": { + "0": { + "0": { + "0": {}, + "1": { + "0": { + "0": {}, + "1": { + "0": { + "0": { + "$selected": true + } } } } @@ -1313,8 +1390,8 @@ }, "transform": { "translate": { - "x": -138, - "y": -122 + "x": -194, + "y": -37 }, "scale": 1 }, @@ -1339,10 +1416,12 @@ "logsPanelFilter": "all", "selectedStylePropertyName": "", "lvglPart": "MAIN", - "lvglState": "DISABLED", + "lvglState": "DEFAULT", "lvglExpandedPropertiesGroup": [ - "MARGIN", - "TEXT" + "TEXT", + "ARC", + "POSITION AND SIZE", + "PADDING" ], "showInactiveFlowsInDebugger": true, "globalFlowZoom": true, diff --git a/internal/native/eez/src/ui/actions.c b/internal/native/eez/src/ui/actions.c index 66e48987..bfa33da1 100644 --- a/internal/native/eez/src/ui/actions.c +++ b/internal/native/eez/src/ui/actions.c @@ -40,7 +40,7 @@ void action_menu_advanced_screen_gesture(lv_event_t * e) { } void action_reset_config_screen_gesture(lv_event_t * e) { - handle_gesture_screen_switch(e, LV_DIR_RIGHT, SCREEN_ID_MENU_ADVANCED_SCREEN); + handle_gesture_screen_switch(e, LV_DIR_RIGHT, SCREEN_ID_MENU_SCREEN); } void action_home_screen_gesture(lv_event_t * e) { diff --git a/internal/native/eez/src/ui/actions.h b/internal/native/eez/src/ui/actions.h index a24b416a..398ff723 100644 --- a/internal/native/eez/src/ui/actions.h +++ b/internal/native/eez/src/ui/actions.h @@ -20,6 +20,7 @@ extern void action_about_screen_gesture(lv_event_t * e); extern void action_switch_to_status(lv_event_t * e); extern void action_common_click_event(lv_event_t * e); extern void action_handle_common_press_event(lv_event_t * e); +extern void action_reset_config(lv_event_t * e); #ifdef __cplusplus diff --git a/internal/native/eez/src/ui/screens.c b/internal/native/eez/src/ui/screens.c index a7c4944b..bead8c86 100644 --- a/internal/native/eez/src/ui/screens.c +++ b/internal/native/eez/src/ui/screens.c @@ -1719,6 +1719,188 @@ void create_screen_status_screen() { void tick_screen_status_screen() { } +void create_screen_reset_config_screen() { + lv_obj_t *obj = lv_obj_create(0); + objects.reset_config_screen = obj; + lv_obj_set_pos(obj, 0, 0); + lv_obj_set_size(obj, 300, 240); + lv_obj_add_event_cb(obj, action_about_screen_gesture, LV_EVENT_GESTURE, (void *)0); + add_style_flex_screen_menu(obj); + { + lv_obj_t *parent_obj = obj; + { + lv_obj_t *obj = lv_obj_create(parent_obj); + lv_obj_set_pos(obj, 0, 0); + lv_obj_set_size(obj, LV_PCT(100), LV_PCT(100)); + lv_obj_set_style_pad_left(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_right(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_bg_opa(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_clear_flag(obj, LV_OBJ_FLAG_SCROLLABLE); + add_style_flex_start(obj); + { + lv_obj_t *parent_obj = obj; + { + // AboutHeaderContainer_1 + lv_obj_t *obj = lv_obj_create(parent_obj); + objects.about_header_container_1 = obj; + lv_obj_set_pos(obj, 0, 0); + lv_obj_set_size(obj, LV_PCT(100), LV_SIZE_CONTENT); + lv_obj_set_style_pad_left(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_bg_opa(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + add_style_flow_row_space_between(obj); + lv_obj_set_style_pad_right(obj, 4, LV_PART_MAIN | LV_STATE_DEFAULT); + { + lv_obj_t *parent_obj = obj; + { + lv_obj_t *obj = lv_button_create(parent_obj); + lv_obj_set_pos(obj, 0, 0); + lv_obj_set_size(obj, 32, 32); + lv_obj_add_event_cb(obj, action_switch_to_menu, LV_EVENT_CLICKED, (void *)0); + add_style_back_button(obj); + { + lv_obj_t *parent_obj = obj; + { + lv_obj_t *obj = lv_image_create(parent_obj); + lv_obj_set_pos(obj, -1, 2); + lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT); + lv_image_set_src(obj, &img_back_caret); + } + } + } + { + lv_obj_t *obj = lv_label_create(parent_obj); + lv_obj_set_pos(obj, LV_PCT(0), LV_PCT(0)); + lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT); + add_style_header_link(obj); + lv_label_set_text(obj, "Reset Device"); + } + } + } + { + // AboutItemsContainer_1 + lv_obj_t *obj = lv_obj_create(parent_obj); + objects.about_items_container_1 = obj; + lv_obj_set_pos(obj, 0, 0); + lv_obj_set_size(obj, LV_PCT(100), LV_PCT(80)); + lv_obj_set_style_pad_left(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_bg_opa(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_scrollbar_mode(obj, LV_SCROLLBAR_MODE_AUTO); + lv_obj_set_scroll_dir(obj, LV_DIR_VER); + lv_obj_set_scroll_snap_x(obj, LV_SCROLL_SNAP_START); + add_style_flex_column_start(obj); + lv_obj_set_style_pad_right(obj, 4, LV_PART_MAIN | LV_STATE_DEFAULT); + { + lv_obj_t *parent_obj = obj; + { + lv_obj_t *obj = lv_obj_create(parent_obj); + lv_obj_set_pos(obj, 0, 0); + lv_obj_set_size(obj, LV_PCT(100), LV_SIZE_CONTENT); + lv_obj_set_style_pad_left(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_bg_opa(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_clear_flag(obj, LV_OBJ_FLAG_SCROLLABLE); + add_style_flex_column_start(obj); + lv_obj_set_style_pad_right(obj, 10, LV_PART_MAIN | LV_STATE_DEFAULT); + { + lv_obj_t *parent_obj = obj; + { + // systemVersionContainer_1 + lv_obj_t *obj = lv_obj_create(parent_obj); + objects.system_version_container_1 = obj; + lv_obj_set_pos(obj, 0, 0); + lv_obj_set_size(obj, LV_PCT(100), LV_SIZE_CONTENT); + lv_obj_set_style_bg_opa(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_clear_flag(obj, LV_OBJ_FLAG_SCROLLABLE); + add_style_flex_column_start(obj); + lv_obj_set_style_pad_right(obj, 10, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_left(obj, 10, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(obj, 10, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(obj, 10, LV_PART_MAIN | LV_STATE_DEFAULT); + { + lv_obj_t *parent_obj = obj; + { + // systemVersion_1 + lv_obj_t *obj = lv_label_create(parent_obj); + objects.system_version_1 = obj; + lv_obj_set_pos(obj, 0, 0); + lv_obj_set_size(obj, LV_PCT(100), LV_SIZE_CONTENT); + add_style_info_content_label(obj); + lv_obj_set_style_text_font(obj, &ui_font_font_book20, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_label_set_text(obj, "Press and hold for\n20 seconds"); + } + } + } + { + // appVersionContainer_1 + lv_obj_t *obj = lv_obj_create(parent_obj); + objects.app_version_container_1 = obj; + lv_obj_set_pos(obj, 0, 0); + lv_obj_set_size(obj, LV_PCT(100), LV_SIZE_CONTENT); + lv_obj_set_style_pad_left(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_top(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_right(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_bottom(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_bg_opa(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_border_width(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_clear_flag(obj, LV_OBJ_FLAG_SCROLLABLE); + add_style_flex_column_start(obj); + { + lv_obj_t *parent_obj = obj; + { + lv_obj_t *obj = lv_button_create(parent_obj); + objects.obj0 = obj; + lv_obj_set_pos(obj, 0, 0); + lv_obj_set_size(obj, LV_PCT(100), 50); + lv_obj_add_event_cb(obj, action_reset_config, LV_EVENT_LONG_PRESSED, (void *)0); + lv_obj_set_style_bg_color(obj, lv_color_hex(0xffdc2626), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_align(obj, LV_TEXT_ALIGN_LEFT, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_right(obj, 13, LV_PART_MAIN | LV_STATE_DEFAULT); + { + lv_obj_t *parent_obj = obj; + { + lv_obj_t *obj = lv_label_create(parent_obj); + lv_obj_set_pos(obj, 0, 0); + lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT); + lv_obj_set_style_align(obj, LV_ALIGN_CENTER, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_align(obj, LV_TEXT_ALIGN_LEFT, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_label_set_text(obj, "Hold to reset"); + } + } + } + } + } + } + } + } + } + } + } + } + + tick_screen_reset_config_screen(); +} + +void tick_screen_reset_config_screen() { +} + typedef void (*tick_screen_func_t)(); @@ -1731,6 +1913,7 @@ tick_screen_func_t tick_screen_funcs[] = { tick_screen_menu_network_screen, tick_screen_about_screen, tick_screen_status_screen, + tick_screen_reset_config_screen, }; void tick_screen(int screen_index) { tick_screen_funcs[screen_index](); @@ -1752,4 +1935,5 @@ void create_screens() { create_screen_menu_network_screen(); create_screen_about_screen(); create_screen_status_screen(); + create_screen_reset_config_screen(); } diff --git a/internal/native/eez/src/ui/screens.h b/internal/native/eez/src/ui/screens.h index b13b19d0..711ae743 100644 --- a/internal/native/eez/src/ui/screens.h +++ b/internal/native/eez/src/ui/screens.h @@ -16,6 +16,7 @@ typedef struct _objects_t { lv_obj_t *menu_network_screen; lv_obj_t *about_screen; lv_obj_t *status_screen; + lv_obj_t *reset_config_screen; lv_obj_t *boot_logo; lv_obj_t *boot_screen_version; lv_obj_t *no_network_header_container; @@ -83,6 +84,12 @@ typedef struct _objects_t { lv_obj_t *app_version_1; lv_obj_t *cloud_domain_container; lv_obj_t *cloud_domain; + lv_obj_t *about_header_container_1; + lv_obj_t *about_items_container_1; + lv_obj_t *system_version_container_1; + lv_obj_t *system_version_1; + lv_obj_t *app_version_container_1; + lv_obj_t *obj0; } objects_t; extern objects_t objects; @@ -96,6 +103,7 @@ enum ScreensEnum { SCREEN_ID_MENU_NETWORK_SCREEN = 6, SCREEN_ID_ABOUT_SCREEN = 7, SCREEN_ID_STATUS_SCREEN = 8, + SCREEN_ID_RESET_CONFIG_SCREEN = 9, }; void create_screen_boot_screen(); @@ -121,6 +129,9 @@ void tick_screen_about_screen(); void create_screen_status_screen(); void tick_screen_status_screen(); + +void create_screen_reset_config_screen(); +void tick_screen_reset_config_screen(); void tick_screen_by_id(enum ScreensEnum screenId); void tick_screen(int screen_index); diff --git a/internal/network/lldp.go b/internal/network/lldp.go deleted file mode 100644 index 8a3e214f..00000000 --- a/internal/network/lldp.go +++ /dev/null @@ -1,46 +0,0 @@ -package network - -import ( - "errors" - - "github.com/jetkvm/kvm/internal/lldp" -) - -func (s *NetworkInterfaceState) shouldStartLLDP() bool { - if s.lldp == nil { - s.l.Trace().Msg("LLDP not initialized") - return false - } - - s.l.Trace().Msgf("LLDP mode: %s", s.config.LLDPMode.String) - - return s.config.LLDPMode.String != "disabled" -} - -func (s *NetworkInterfaceState) startLLDP() { - if !s.shouldStartLLDP() || s.lldp == nil { - return - } - - s.l.Trace().Msg("starting LLDP") - if err := s.lldp.Start(); err != nil { - s.l.Error().Err(err).Msg("unable to start LLDP") - } -} - -func (s *NetworkInterfaceState) stopLLDP() { - if s.lldp == nil { - return - } - s.l.Trace().Msg("stopping LLDP") - if err := s.lldp.Stop(); err != nil { - s.l.Error().Err(err).Msg("unable to stop LLDP") - } -} - -func (s *NetworkInterfaceState) GetLLDPNeighbors() ([]lldp.Neighbor, error) { - if s.lldp == nil { - return nil, errors.New("lldp not initialized") - } - return s.lldp.GetNeighbors(), nil -} diff --git a/internal/network/netif.go b/internal/network/netif.go index c7c03e6d..d237e31a 100644 --- a/internal/network/netif.go +++ b/internal/network/netif.go @@ -6,7 +6,6 @@ import ( "sync" "github.com/jetkvm/kvm/internal/confparser" - "github.com/jetkvm/kvm/internal/lldp" "github.com/jetkvm/kvm/internal/logging" "github.com/jetkvm/kvm/internal/udhcpc" "github.com/rs/zerolog" @@ -31,8 +30,6 @@ type NetworkInterfaceState struct { config *NetworkConfig dhcpClient *udhcpc.DHCPClient - lldp *lldp.LLDP - defaultHostname string currentHostname string currentFqdn string @@ -101,24 +98,7 @@ func NewNetworkInterfaceState(opts *NetworkInterfaceOptions) (*NetworkInterfaceS }, }) - // create the lldp service - lldpClient := lldp.NewLLDP(&lldp.LLDPOptions{ - InterfaceName: opts.InterfaceName, - EnableRx: true, - EnableTx: true, - Logger: l, - }) - - // create the lldp service - lldpClient = lldp.NewLLDP(&lldp.LLDPOptions{ - InterfaceName: opts.InterfaceName, - EnableRx: true, - EnableTx: true, - Logger: l, - }) - s.dhcpClient = dhcpClient - s.lldp = lldpClient return s, nil } @@ -387,16 +367,13 @@ func (s *NetworkInterfaceState) updateNtpServersFromLease(lease *udhcpc.Lease) e func (s *NetworkInterfaceState) handleInitialCheck() { if s.IsUp() { - s.startLLDP() } s.onInitialCheck(s) } func (s *NetworkInterfaceState) handleStateChange() { if s.IsUp() { - s.startLLDP() } else { - s.stopLLDP() } s.onStateChange(s) } diff --git a/jsonrpc.go b/jsonrpc.go index e94adb65..32f9bb8a 100644 --- a/jsonrpc.go +++ b/jsonrpc.go @@ -1259,5 +1259,4 @@ var rpcHandlers = map[string]RPCHandler{ "setKeyboardMacros": {Func: setKeyboardMacros, Params: []string{"params"}}, "getLocalLoopbackOnly": {Func: rpcGetLocalLoopbackOnly}, "setLocalLoopbackOnly": {Func: rpcSetLocalLoopbackOnly, Params: []string{"enabled"}}, - "getLLDPNeighbors": {Func: rpcGetLLDPNeighbors}, } diff --git a/network.go b/network.go index a6c3e0cc..b808d6fe 100644 --- a/network.go +++ b/network.go @@ -3,7 +3,6 @@ package kvm import ( "fmt" - "github.com/jetkvm/kvm/internal/lldp" "github.com/jetkvm/kvm/internal/network" "github.com/jetkvm/kvm/internal/udhcpc" ) @@ -124,7 +123,3 @@ func rpcSetNetworkSettings(settings network.RpcNetworkSettings) (*network.RpcNet func rpcRenewDHCPLease() error { return networkState.RpcRenewDHCPLease() } - -func rpcGetLLDPNeighbors() ([]lldp.Neighbor, error) { - return networkState.GetLLDPNeighbors() -}