Add USB/IP service

This commit is contained in:
世界
2026-06-14 19:19:46 +08:00
parent 12f160ab5f
commit 7cffd47dd4
30 changed files with 3117 additions and 246 deletions
+112 -1
View File
@@ -673,7 +673,7 @@ func (c *CommandClient) TriggerNativeCrash() error {
}
func (c *CommandClient) TriggerOOMReport() error {
_, err := callWithResult(c, func(ctx context.Context, client daemon.StartedServiceClient) (*emptypb.Empty, error) {
_, err := callManagedWithResult(c, func(ctx context.Context, client daemon.ManagedServiceClient) (*emptypb.Empty, error) {
return client.TriggerOOMReport(ctx, &emptypb.Empty{})
})
if err != nil {
@@ -924,6 +924,61 @@ func (c *CommandClient) SubscribeTailscaleStatus(handler TailscaleStatusHandler)
return session, nil
}
func (c *CommandClient) SubscribeUSBIPServerStatus(handler USBIPServerStatusHandler) (*USBIPServerStatusSubscription, error) {
client, parentCtx, err := c.getClientForCall()
if err != nil {
return nil, E.Cause(err, "subscribe usbip server status")
}
streamCtx, cancel := context.WithCancel(parentCtx)
session := &USBIPServerStatusSubscription{
streamSession: streamSession{
ctx: streamCtx,
cancel: cancel,
closeDone: make(chan struct{}),
},
}
failStart := func(cause error, message string) (*USBIPServerStatusSubscription, error) {
cancel()
if c.standalone {
c.closeConnection()
}
return nil, E.Cause(cause, message)
}
stream, err := client.SubscribeUSBIPServerStatus(streamCtx, &emptypb.Empty{})
if err != nil {
return failStart(err, "subscribe usbip server status")
}
standalone := c.standalone
go func() {
defer func() {
close(session.closeDone)
if standalone {
c.closeConnection()
}
}()
for {
event, recvErr := stream.Recv()
if recvErr != nil {
if session.ctx.Err() != nil {
return
}
if status.Code(recvErr) == codes.NotFound || status.Code(recvErr) == codes.Unavailable {
return
}
handler.OnError(E.Cause(recvErr, "usbip server status recv").Error())
return
}
handler.OnStatusUpdate(usbipServerStatusUpdateFromGRPC(event))
}
}()
return session, nil
}
func (c *CommandClient) SetTailscaleExitNode(endpointTag string, stableID string) error {
_, err := callWithResult(c, func(ctx context.Context, client daemon.StartedServiceClient) (*emptypb.Empty, error) {
return client.SetTailscaleExitNode(ctx, &daemon.SetTailscaleExitNodeRequest{
@@ -1125,3 +1180,59 @@ func (c *CommandClient) StartTailscaleSSHSession(opts *TailscaleSSHOptions, hand
return session, nil
}
func (c *CommandClient) ProvideUSBDevices(handler USBProviderHandler) (*USBProviderSession, error) {
client, parentCtx, err := c.getClientForCall()
if err != nil {
return nil, E.Cause(err, "provide usb devices")
}
streamCtx, cancel := context.WithCancel(parentCtx)
stream, err := client.ProvideUSBDevices(streamCtx)
if err != nil {
cancel()
if c.standalone {
c.closeConnection()
}
return nil, E.Cause(err, "provide usb devices")
}
session := &USBProviderSession{
stream: stream,
ctx: streamCtx,
cancel: cancel,
closeDone: make(chan struct{}),
}
standalone := c.standalone
go func() {
defer close(session.closeDone)
for {
message, recvErr := stream.Recv()
if recvErr == io.EOF {
cancel()
break
}
if recvErr != nil {
handler.OnError("", E.Cause(recvErr, "usb provider recv").Error())
cancel()
break
}
switch payload := message.GetMessage().(type) {
case *daemon.USBServerMessage_Ready:
handler.OnReady(payload.Ready.GetDeviceId(), payload.Ready.GetBusId())
case *daemon.USBServerMessage_UrbRequest:
handler.OnURBRequest(usbURBRequestFromGRPC(payload.UrbRequest))
case *daemon.USBServerMessage_Abort:
handler.OnAbort(payload.Abort.GetDeviceId(), int32(payload.Abort.GetEndpoint()))
case *daemon.USBServerMessage_Error:
handler.OnError(payload.Error.GetDeviceId(), payload.Error.GetMessage())
}
}
if standalone {
c.closeConnection()
}
}()
return session, nil
}