mirror of
https://github.com/sipeed/NanoKVM.git
synced 2026-09-11 00:22:56 -05:00
server side for full gadget disable
starting on frontend
This commit is contained in:
@@ -106,7 +106,9 @@ start_usb_dev(){
|
||||
fi
|
||||
fi
|
||||
|
||||
ls /sys/class/udc/ | cat > UDC
|
||||
if [ ! -e /boot/udc.disable ]; then
|
||||
ls /sys/class/udc/ | cat > UDC
|
||||
fi
|
||||
echo device > /proc/cviusb/otg_role
|
||||
}
|
||||
|
||||
@@ -118,7 +120,9 @@ start_usb_host(){
|
||||
restart_usb_dev(){
|
||||
echo > /sys/kernel/config/usb_gadget/g0/UDC
|
||||
sleep 1
|
||||
ls /sys/class/udc/ | cat > /sys/kernel/config/usb_gadget/g0/UDC
|
||||
if [ ! -e /boot/udc.disable ]; then
|
||||
ls /sys/class/udc/ | cat > /sys/kernel/config/usb_gadget/g0/UDC
|
||||
fi
|
||||
echo "USB Restart OK!"
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,9 @@ start_usb_dev(){
|
||||
echo -ne \\x05\\x01\\x09\\x02\\xa1\\x01\\x09\\x01\\xa1\\x00\\x05\\x09\\x19\\x01\\x29\\x03\\x15\\x00\\x25\\x01\\x95\\x03\\x75\\x01\\x81\\x02\\x95\\x01\\x75\\x05\\x81\\x01\\x05\\x01\\x09\\x30\\x09\\x31\\x15\\x00\\x26\\xff\\x7f\\x35\\x00\\x46\\xff\\x7f\\x75\\x10\\x95\\x02\\x81\\x02\\x05\\x01\\x09\\x38\\x15\\x81\\x25\\x7f\\x35\\x00\\x45\\x00\\x75\\x08\\x95\\x01\\x81\\x06\\xc0\\xc0 > functions/hid.GS2/report_desc
|
||||
ln -s functions/hid.GS2 configs/c.1
|
||||
|
||||
ls /sys/class/udc/ | cat > UDC
|
||||
if [ ! -e /boot/udc.disable ]; then
|
||||
ls /sys/class/udc/ | cat > UDC
|
||||
fi
|
||||
echo device > /proc/cviusb/otg_role
|
||||
}
|
||||
|
||||
@@ -72,7 +74,9 @@ start_usb_host(){
|
||||
restart_usb_dev(){
|
||||
echo > /sys/kernel/config/usb_gadget/g0/UDC
|
||||
sleep 1
|
||||
ls /sys/class/udc/ | cat > /sys/kernel/config/usb_gadget/g0/UDC
|
||||
if [ ! -e /boot/udc.disable ]; then
|
||||
ls /sys/class/udc/ | cat > /sys/kernel/config/usb_gadget/g0/UDC
|
||||
fi
|
||||
echo "USB Restart OK!"
|
||||
}
|
||||
|
||||
|
||||
@@ -91,6 +91,10 @@ type GetGetHdmiStateRsp struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
}
|
||||
|
||||
type GetUsbStateRsp struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
}
|
||||
|
||||
type GetSSHStateRsp struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
}
|
||||
|
||||
@@ -35,6 +35,10 @@ func vmRouter(r *gin.Engine) {
|
||||
api.GET("/vm/oled", service.GetOLED) // get OLED configuration
|
||||
api.POST("/vm/oled", service.SetOLED) // set OLED configuration
|
||||
|
||||
api.GET("/vm/usb", service.GetUsbState) // get USB gadget state
|
||||
api.POST("/vm/usb/enable", service.EnableUsb) // enable USB
|
||||
api.POST("/vm/usb/disable", service.DisableUsb) // disable USB
|
||||
|
||||
// Only supported by PCIe version
|
||||
api.GET("/vm/hdmi", service.GetHdmiState) // get HDMI state
|
||||
api.POST("/vm/hdmi/reset", service.ResetHdmi) // reset hdmi
|
||||
|
||||
86
server/service/vm/usb.go
Normal file
86
server/service/vm/usb.go
Normal file
@@ -0,0 +1,86 @@
|
||||
package vm
|
||||
|
||||
import (
|
||||
"NanoKVM-Server/proto"
|
||||
"NanoKVM-Server/service/hid"
|
||||
"os"
|
||||
"os/exec"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const (
|
||||
udcDisableFile = "/boot/udc.disable"
|
||||
)
|
||||
|
||||
var (
|
||||
udcEnableCommands = []string{
|
||||
"rm /boot/udc.disable",
|
||||
"/etc/init.d/S03usbdev restart",
|
||||
}
|
||||
|
||||
udcDisableCommands = []string{
|
||||
"touch /boot/udc.disable",
|
||||
"/etc/init.d/S03usbdev restart",
|
||||
}
|
||||
)
|
||||
|
||||
func runCommands(commands []string) error {
|
||||
h := hid.GetHid()
|
||||
h.Lock()
|
||||
h.CloseNoLock()
|
||||
defer func() {
|
||||
h.OpenNoLock()
|
||||
h.Unlock()
|
||||
}()
|
||||
|
||||
for _, command := range commands {
|
||||
if err := exec.Command("sh", "-c", command).Run(); err != nil {
|
||||
log.Errorf("failed to run command '%s': %v", command, err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Service) EnableUsb(c *gin.Context) {
|
||||
var rsp proto.Response
|
||||
|
||||
err := runCommands(udcEnableCommands)
|
||||
if err != nil {
|
||||
rsp.ErrRsp(c, -1, "failed to enable USB")
|
||||
return
|
||||
}
|
||||
|
||||
rsp.OkRsp(c)
|
||||
log.Debug("enable usb")
|
||||
}
|
||||
|
||||
func (s *Service) DisableUsb(c *gin.Context) {
|
||||
var rsp proto.Response
|
||||
|
||||
err := runCommands(udcDisableCommands)
|
||||
if err != nil {
|
||||
rsp.ErrRsp(c, -1, "failed to disable USB")
|
||||
return
|
||||
}
|
||||
|
||||
rsp.OkRsp(c)
|
||||
log.Debug("disable usb")
|
||||
}
|
||||
|
||||
func (s *Service) GetUsbState(c *gin.Context) {
|
||||
var rsp proto.Response
|
||||
|
||||
usbEnabled := false
|
||||
if _, err := os.Stat(udcDisableFile); err != nil {
|
||||
usbEnabled = true
|
||||
}
|
||||
|
||||
rsp.OkRspWithData(c, &proto.GetUsbStateRsp{
|
||||
Enabled: usbEnabled,
|
||||
})
|
||||
|
||||
log.Debug("get usb state")
|
||||
}
|
||||
16
web/src/api/usb-device.ts
Normal file
16
web/src/api/usb-device.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { http } from '@/lib/http.ts';
|
||||
|
||||
// get virtual devices status
|
||||
export function getUsbState() {
|
||||
return http.get('/api/vm/usb');
|
||||
}
|
||||
|
||||
// enable usb
|
||||
export function enableUsb() {
|
||||
return http.post('/api/vm/usb/enable');
|
||||
}
|
||||
|
||||
// disable usb
|
||||
export function disableUsb() {
|
||||
return http.post('/api/vm/usb/disable');
|
||||
}
|
||||
@@ -271,6 +271,8 @@ const en = {
|
||||
networkDesc: 'Mount virtual network card on the remote host',
|
||||
reboot: 'Reboot',
|
||||
rebootDesc: 'Are you sure you want to reboot NanoKVM?',
|
||||
usb: 'USB Interface',
|
||||
usbDesc: 'Enable USB to host interface',
|
||||
okBtn: 'Yes',
|
||||
cancelBtn: 'No'
|
||||
},
|
||||
|
||||
@@ -15,7 +15,7 @@ import { Oled } from './oled.tsx';
|
||||
import { Reboot } from './reboot.tsx';
|
||||
import { Ssh } from './ssh.tsx';
|
||||
import { Tls } from './tls.tsx';
|
||||
import { VirtualDevices } from './virtual-devices.tsx';
|
||||
import { Usb } from './usb/index.tsx';
|
||||
import { Wifi } from './wifi.tsx';
|
||||
|
||||
export const Device = () => {
|
||||
@@ -42,7 +42,7 @@ export const Device = () => {
|
||||
<Mdns />
|
||||
<Hdmi />
|
||||
|
||||
{hidMode === 'normal' ? <VirtualDevices /> : <HidMode />}
|
||||
{hidMode === 'normal' ? <Usb/> : <HidMode />}
|
||||
</div>
|
||||
<Divider />
|
||||
|
||||
|
||||
55
web/src/pages/desktop/menu/settings/device/usb/index.tsx
Normal file
55
web/src/pages/desktop/menu/settings/device/usb/index.tsx
Normal file
@@ -0,0 +1,55 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Switch } from 'antd';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { VirtualDevices } from './virtual-devices.tsx';
|
||||
import * as api from '@/api/usb-device.ts';
|
||||
|
||||
|
||||
export const Usb = () => {
|
||||
const { t } = useTranslation();
|
||||
const [isUsbOn, setIsUsbOn] = useState(false);
|
||||
const [isLoading, setLoading] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
api.getUsbState().then((rsp) => {
|
||||
if (rsp.code !== 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
setIsUsbOn(rsp.data.enabled);
|
||||
});
|
||||
}, []);
|
||||
|
||||
function update() {
|
||||
if (isLoading) return;
|
||||
setLoading(true);
|
||||
|
||||
const func = isUsbOn ? api.disableUsb() : api.enableUsb();
|
||||
|
||||
func.then((rsp) => {
|
||||
if (rsp.code !== 0) {
|
||||
return;
|
||||
}
|
||||
setIsUsbOn(!isUsbOn);
|
||||
})
|
||||
.finally(() => {
|
||||
setLoading(false);
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex flex-col">
|
||||
<span>{t('settings.device.usb')}</span>
|
||||
<span className="text-xs text-neutral-500">{t('settings.device.usbDesc')}</span>
|
||||
</div>
|
||||
|
||||
<Switch checked={isUsbOn} loading={isLoading} onChange={() => update()} />
|
||||
</div>
|
||||
|
||||
{isUsbOn ? <VirtualDevices /> : ""}
|
||||
</>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user