diff --git a/cli_client/cmd_usb.go b/cli_client/cmd_usb.go index 63b61bb..b27006e 100644 --- a/cli_client/cmd_usb.go +++ b/cli_client/cmd_usb.go @@ -6,20 +6,24 @@ import ( "log" "github.com/davecgh/go-spew/spew" + "google.golang.org/grpc/status" ) //Empty settings used to store cobra flags var ( //tmpGadgetSettings = pb.GadgetSettings{CdcEcmSettings:&pb.GadgetSettingsEthernet{},RndisSettings:&pb.GadgetSettingsEthernet{}} - tmpNoAutoDeploy = false - tmpDisableGadget bool = false - tmpUseHIDKeyboard uint8 = 0 - tmpUseHIDMouse uint8 = 0 - tmpUseHIDRaw uint8 = 0 - tmpUseRNDIS uint8 = 0 - tmpUseECM uint8 = 0 - tmpUseSerial uint8 = 0 - tmpUseUMS uint8 = 0 + tmpNoAutoDeploy = false + tmpDisableGadget bool = false + tmpUseHIDKeyboard uint8 = 0 + tmpUseHIDMouse uint8 = 0 + tmpUseHIDRaw uint8 = 0 + tmpUseRNDIS uint8 = 0 + tmpUseECM uint8 = 0 + tmpUseSerial uint8 = 0 + tmpUseUMS uint8 = 0 + tmpUMSFile string = "" + tmpUMSCdromMode bool = false + ) func init(){ @@ -73,10 +77,10 @@ func cobraUsbSet(cmd *cobra.Command, args []string) { fmt.Printf("Old USB Gadget Settings:\n%s", spew.Sdump(gs)) if tmpDisableGadget { - fmt.Println("Gadget set to disabled (won't get bound to UDC after deployment)") + fmt.Println("Setting gadget to disabled (won't get bound to UDC after deployment)") gs.Enabled = false } else { - fmt.Println("Gadget set to enabled (will be usable after deployment)") + fmt.Println("Setting gadget to enabled (will be usable after deployment)") gs.Enabled = true } @@ -140,6 +144,7 @@ func cobraUsbSet(cmd *cobra.Command, args []string) { } } + //ToDo: Implement detailed UMS settings if (cmd.Flags().Lookup("ums").Changed) { if tmpUseUMS == 0 { fmt.Println("Disabeling USB Mass Storage") @@ -147,16 +152,30 @@ func cobraUsbSet(cmd *cobra.Command, args []string) { } else { fmt.Println("Enabeling USB Mass Storage") gs.Use_UMS = true + + gs.UmsSettings.Cdrom = tmpUMSCdromMode + if tmpUMSCdromMode { + fmt.Println("Setting USB Mass Storage to CD-Rom mode") + } else { + fmt.Println("Setting USB Mass Storage to flash drive mode") + } + + if cmd.Flags().Lookup("ums-file").Changed { + fmt.Printf("Serving USB Mass Storage from '%s'\n", tmpUMSFile) + gs.UmsSettings.File = tmpUMSFile + } } } - //ToDo: Implement detailed UMS settings + //Try to set the change config + //ToDo: Adopt parsing of Error Message to other gRPC calls err = ClientSetGadgetSettings(StrRemoteHost, StrRemotePort, *gs) if err != nil { - log.Printf("Error setting new gadget settings: %v\n", err) + log.Printf("Error setting new gadget settings: %v\n", status.Convert(err).Message()) + return } gs, err = ClientGetGadgetSettings(StrRemoteHost, StrRemotePort) @@ -224,5 +243,8 @@ func init() { usbSetCmd.Flags().Uint8VarP(&tmpUseHIDMouse, "hid-mouse", "m",0,"Use the HID MOUSE gadget function (0: disable, 1..n: enable)") usbSetCmd.Flags().Uint8VarP(&tmpUseHIDRaw, "hid-raw", "g",0,"Use the HID RAW gadget function (0: disable, 1..n: enable)") - usbSetCmd.Flags().Uint8VarP(&tmpUseUMS, "ums", "u",0,"Use the USB MAss Storage gadget function (0: disable, 1..n: enable)") + usbSetCmd.Flags().Uint8VarP(&tmpUseUMS, "ums", "u",0,"Use the USB Mass Storage gadget function (0: disable, 1..n: enable)") + + usbSetCmd.Flags().BoolVar(&tmpUMSCdromMode, "ums-cdrom", false, "If this flag is set, UMS emulates a CD-Rom instead of a flashdrive (ignored, if UMS disabled)") + usbSetCmd.Flags().StringVar(&tmpUMSFile, "ums-file", "", "Path to the image or block device backing UMS (ignored, if UMS disabled)") } diff --git a/cli_client/rpc.go b/cli_client/rpc.go index 17a0209..71c089c 100644 --- a/cli_client/rpc.go +++ b/cli_client/rpc.go @@ -36,40 +36,38 @@ func ClientConnectServer(rpcHost string, rpcPort string) ( func ClientGetLED(host string, port string) (ls *pb.LEDSettings, err error) { conn, client, ctx, cancel, err := ClientConnectServer(host, port) - if err != nil { - return - } + defer conn.Close() + defer cancel() + if err != nil { return } ls, err = client.GetLEDSettings(ctx, &pb.Empty{}) if err != nil { log.Printf("Error getting LED blink count: %v", err) } - ClientDisconnectServer(cancel, conn) return } func ClientGetGadgetSettings(host string, port string) (gs *pb.GadgetSettings, err error) { conn, client, ctx, cancel, err := ClientConnectServer(host, port) - if err != nil { - return - } + defer conn.Close() + defer cancel() + if err != nil { return } gs, err = client.GetGadgetSettings(ctx, &pb.Empty{}) if err != nil { log.Printf("Error getting USB Gadget Settings: %+v", err) } - ClientDisconnectServer(cancel, conn) return } func ClientDeployGadgetSettings(host string, port string) (gs *pb.GadgetSettings, err error) { conn, client, ctx, cancel, err := ClientConnectServer(host, port) - if err != nil { - return - } - defer ClientDisconnectServer(cancel, conn) + defer conn.Close() + defer cancel() + if err != nil { return } + gs, err = client.DeployGadgetSetting(ctx, &pb.Empty{}) if err != nil { @@ -85,52 +83,54 @@ func ClientDeployGadgetSettings(host string, port string) (gs *pb.GadgetSettings func ClientGetDeployedGadgetSettings(host string, port string) (gs *pb.GadgetSettings, err error) { conn, client, ctx, cancel, err := ClientConnectServer(host, port) - if err != nil { - return - } + defer conn.Close() + defer cancel() + if err != nil { return } gs, err = client.GetDeployedGadgetSetting(ctx, &pb.Empty{}) if err != nil { log.Printf("Error getting USB Gadget Settings count: %+v", err) } - ClientDisconnectServer(cancel, conn) return } func ClientSetGadgetSettings(host string, port string, gs pb.GadgetSettings) (err error) { conn, client, ctx, cancel, err := ClientConnectServer(host, port) - if err != nil { - return - } + defer conn.Close() + defer cancel() + if err != nil { return } _, err = client.SetGadgetSettings(ctx, &gs) + //Only forward the error + /* if err != nil { log.Printf("Error setting GadgetSettings %d: %+v", gs, err) } - - ClientDisconnectServer(cancel, conn) + */ return } func ClientSetLED(host string, port string, ls pb.LEDSettings) (err error) { conn, client, ctx, cancel, err := ClientConnectServer(host, port) - if err != nil { - return - } + defer conn.Close() + defer cancel() + if err != nil { return } _, err = client.SetLEDSettings(ctx, &ls) if err != nil { log.Printf("Error setting LED blink count %d: %v", ls.BlinkCount, err) } - ClientDisconnectServer(cancel, conn) + return } +/* func ClientDisconnectServer(cancel context.CancelFunc, connection *grpc.ClientConn) error { defer connection.Close() defer cancel() return nil } +*/ \ No newline at end of file diff --git a/proto/grpc.pb.go b/proto/grpc.pb.go index b4aa21d..a8f27da 100644 --- a/proto/grpc.pb.go +++ b/proto/grpc.pb.go @@ -9,8 +9,9 @@ It is generated from these files: It has these top-level messages: LEDSettings - GadgetSettingsEthernet GadgetSettings + GadgetSettingsEthernet + GadgetSettingsUMS WiFiSettings Empty */ @@ -58,7 +59,7 @@ var WiFiSettings_Mode_value = map[string]int32{ func (x WiFiSettings_Mode) String() string { return proto.EnumName(WiFiSettings_Mode_name, int32(x)) } -func (WiFiSettings_Mode) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{3, 0} } +func (WiFiSettings_Mode) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{4, 0} } type WiFiSettings_APAuthMode int32 @@ -79,7 +80,7 @@ var WiFiSettings_APAuthMode_value = map[string]int32{ func (x WiFiSettings_APAuthMode) String() string { return proto.EnumName(WiFiSettings_APAuthMode_name, int32(x)) } -func (WiFiSettings_APAuthMode) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{3, 1} } +func (WiFiSettings_APAuthMode) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{4, 1} } type LEDSettings struct { BlinkCount uint32 `protobuf:"varint,1,opt,name=blink_count,json=blinkCount" json:"blink_count,omitempty"` @@ -97,30 +98,6 @@ func (m *LEDSettings) GetBlinkCount() uint32 { return 0 } -type GadgetSettingsEthernet struct { - HostAddr string `protobuf:"bytes,1,opt,name=host_addr,json=hostAddr" json:"host_addr,omitempty"` - DevAddr string `protobuf:"bytes,2,opt,name=dev_addr,json=devAddr" json:"dev_addr,omitempty"` -} - -func (m *GadgetSettingsEthernet) Reset() { *m = GadgetSettingsEthernet{} } -func (m *GadgetSettingsEthernet) String() string { return proto.CompactTextString(m) } -func (*GadgetSettingsEthernet) ProtoMessage() {} -func (*GadgetSettingsEthernet) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } - -func (m *GadgetSettingsEthernet) GetHostAddr() string { - if m != nil { - return m.HostAddr - } - return "" -} - -func (m *GadgetSettingsEthernet) GetDevAddr() string { - if m != nil { - return m.DevAddr - } - return "" -} - type GadgetSettings struct { Enabled bool `protobuf:"varint,1,opt,name=enabled" json:"enabled,omitempty"` Vid string `protobuf:"bytes,2,opt,name=vid" json:"vid,omitempty"` @@ -137,12 +114,13 @@ type GadgetSettings struct { Use_SERIAL bool `protobuf:"varint,13,opt,name=use_SERIAL,json=useSERIAL" json:"use_SERIAL,omitempty"` RndisSettings *GadgetSettingsEthernet `protobuf:"bytes,14,opt,name=rndis_settings,json=rndisSettings" json:"rndis_settings,omitempty"` CdcEcmSettings *GadgetSettingsEthernet `protobuf:"bytes,15,opt,name=cdc_ecm_settings,json=cdcEcmSettings" json:"cdc_ecm_settings,omitempty"` + UmsSettings *GadgetSettingsUMS `protobuf:"bytes,16,opt,name=ums_settings,json=umsSettings" json:"ums_settings,omitempty"` } func (m *GadgetSettings) Reset() { *m = GadgetSettings{} } func (m *GadgetSettings) String() string { return proto.CompactTextString(m) } func (*GadgetSettings) ProtoMessage() {} -func (*GadgetSettings) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } +func (*GadgetSettings) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } func (m *GadgetSettings) GetEnabled() bool { if m != nil { @@ -249,6 +227,61 @@ func (m *GadgetSettings) GetCdcEcmSettings() *GadgetSettingsEthernet { return nil } +func (m *GadgetSettings) GetUmsSettings() *GadgetSettingsUMS { + if m != nil { + return m.UmsSettings + } + return nil +} + +type GadgetSettingsEthernet struct { + HostAddr string `protobuf:"bytes,1,opt,name=host_addr,json=hostAddr" json:"host_addr,omitempty"` + DevAddr string `protobuf:"bytes,2,opt,name=dev_addr,json=devAddr" json:"dev_addr,omitempty"` +} + +func (m *GadgetSettingsEthernet) Reset() { *m = GadgetSettingsEthernet{} } +func (m *GadgetSettingsEthernet) String() string { return proto.CompactTextString(m) } +func (*GadgetSettingsEthernet) ProtoMessage() {} +func (*GadgetSettingsEthernet) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } + +func (m *GadgetSettingsEthernet) GetHostAddr() string { + if m != nil { + return m.HostAddr + } + return "" +} + +func (m *GadgetSettingsEthernet) GetDevAddr() string { + if m != nil { + return m.DevAddr + } + return "" +} + +type GadgetSettingsUMS struct { + Cdrom bool `protobuf:"varint,1,opt,name=cdrom" json:"cdrom,omitempty"` + File string `protobuf:"bytes,2,opt,name=file" json:"file,omitempty"` +} + +func (m *GadgetSettingsUMS) Reset() { *m = GadgetSettingsUMS{} } +func (m *GadgetSettingsUMS) String() string { return proto.CompactTextString(m) } +func (*GadgetSettingsUMS) ProtoMessage() {} +func (*GadgetSettingsUMS) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} } + +func (m *GadgetSettingsUMS) GetCdrom() bool { + if m != nil { + return m.Cdrom + } + return false +} + +func (m *GadgetSettingsUMS) GetFile() string { + if m != nil { + return m.File + } + return "" +} + type WiFiSettings struct { Diasabled bool `protobuf:"varint,1,opt,name=diasabled" json:"diasabled,omitempty"` Reg string `protobuf:"bytes,2,opt,name=reg" json:"reg,omitempty"` @@ -266,7 +299,7 @@ type WiFiSettings struct { func (m *WiFiSettings) Reset() { *m = WiFiSettings{} } func (m *WiFiSettings) String() string { return proto.CompactTextString(m) } func (*WiFiSettings) ProtoMessage() {} -func (*WiFiSettings) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} } +func (*WiFiSettings) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} } func (m *WiFiSettings) GetDiasabled() bool { if m != nil { @@ -351,12 +384,13 @@ type Empty struct { func (m *Empty) Reset() { *m = Empty{} } func (m *Empty) String() string { return proto.CompactTextString(m) } func (*Empty) ProtoMessage() {} -func (*Empty) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} } +func (*Empty) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} } func init() { proto.RegisterType((*LEDSettings)(nil), "P4wnP1_grpc.LEDSettings") - proto.RegisterType((*GadgetSettingsEthernet)(nil), "P4wnP1_grpc.GadgetSettingsEthernet") proto.RegisterType((*GadgetSettings)(nil), "P4wnP1_grpc.GadgetSettings") + proto.RegisterType((*GadgetSettingsEthernet)(nil), "P4wnP1_grpc.GadgetSettingsEthernet") + proto.RegisterType((*GadgetSettingsUMS)(nil), "P4wnP1_grpc.GadgetSettingsUMS") proto.RegisterType((*WiFiSettings)(nil), "P4wnP1_grpc.WiFiSettings") proto.RegisterType((*Empty)(nil), "P4wnP1_grpc.Empty") proto.RegisterEnum("P4wnP1_grpc.WiFiSettings_Mode", WiFiSettings_Mode_name, WiFiSettings_Mode_value) @@ -380,8 +414,7 @@ type P4WNP1Client interface { SetGadgetSettings(ctx context.Context, in *GadgetSettings, opts ...grpc.CallOption) (*GadgetSettings, error) GetLEDSettings(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*LEDSettings, error) SetLEDSettings(ctx context.Context, in *LEDSettings, opts ...grpc.CallOption) (*Empty, error) - StopGadget(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Empty, error) - StartGadget(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Empty, error) + MountUMSFile(ctx context.Context, in *GadgetSettingsUMS, opts ...grpc.CallOption) (*Empty, error) } type p4WNP1Client struct { @@ -446,18 +479,9 @@ func (c *p4WNP1Client) SetLEDSettings(ctx context.Context, in *LEDSettings, opts return out, nil } -func (c *p4WNP1Client) StopGadget(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Empty, error) { +func (c *p4WNP1Client) MountUMSFile(ctx context.Context, in *GadgetSettingsUMS, opts ...grpc.CallOption) (*Empty, error) { out := new(Empty) - err := grpc.Invoke(ctx, "/P4wnP1_grpc.P4WNP1/StopGadget", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *p4WNP1Client) StartGadget(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Empty, error) { - out := new(Empty) - err := grpc.Invoke(ctx, "/P4wnP1_grpc.P4WNP1/StartGadget", in, out, c.cc, opts...) + err := grpc.Invoke(ctx, "/P4wnP1_grpc.P4WNP1/MountUMSFile", in, out, c.cc, opts...) if err != nil { return nil, err } @@ -473,8 +497,7 @@ type P4WNP1Server interface { SetGadgetSettings(context.Context, *GadgetSettings) (*GadgetSettings, error) GetLEDSettings(context.Context, *Empty) (*LEDSettings, error) SetLEDSettings(context.Context, *LEDSettings) (*Empty, error) - StopGadget(context.Context, *Empty) (*Empty, error) - StartGadget(context.Context, *Empty) (*Empty, error) + MountUMSFile(context.Context, *GadgetSettingsUMS) (*Empty, error) } func RegisterP4WNP1Server(s *grpc.Server, srv P4WNP1Server) { @@ -589,38 +612,20 @@ func _P4WNP1_SetLEDSettings_Handler(srv interface{}, ctx context.Context, dec fu return interceptor(ctx, in, info, handler) } -func _P4WNP1_StopGadget_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(Empty) +func _P4WNP1_MountUMSFile_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GadgetSettingsUMS) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(P4WNP1Server).StopGadget(ctx, in) + return srv.(P4WNP1Server).MountUMSFile(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/P4wnP1_grpc.P4WNP1/StopGadget", + FullMethod: "/P4wnP1_grpc.P4WNP1/MountUMSFile", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(P4WNP1Server).StopGadget(ctx, req.(*Empty)) - } - return interceptor(ctx, in, info, handler) -} - -func _P4WNP1_StartGadget_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(Empty) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(P4WNP1Server).StartGadget(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/P4wnP1_grpc.P4WNP1/StartGadget", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(P4WNP1Server).StartGadget(ctx, req.(*Empty)) + return srv.(P4WNP1Server).MountUMSFile(ctx, req.(*GadgetSettingsUMS)) } return interceptor(ctx, in, info, handler) } @@ -654,12 +659,8 @@ var _P4WNP1_serviceDesc = grpc.ServiceDesc{ Handler: _P4WNP1_SetLEDSettings_Handler, }, { - MethodName: "StopGadget", - Handler: _P4WNP1_StopGadget_Handler, - }, - { - MethodName: "StartGadget", - Handler: _P4WNP1_StartGadget_Handler, + MethodName: "MountUMSFile", + Handler: _P4WNP1_MountUMSFile_Handler, }, }, Streams: []grpc.StreamDesc{}, @@ -669,56 +670,59 @@ var _P4WNP1_serviceDesc = grpc.ServiceDesc{ func init() { proto.RegisterFile("grpc.proto", fileDescriptor0) } var fileDescriptor0 = []byte{ - // 806 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x95, 0xdf, 0x6e, 0xdb, 0x36, - 0x14, 0xc6, 0xe3, 0xc4, 0xb1, 0xad, 0x23, 0xdb, 0x75, 0x59, 0xac, 0xd3, 0xda, 0xb5, 0x0d, 0xb4, - 0x0e, 0xc8, 0xc5, 0x60, 0xa0, 0x5e, 0xb1, 0xdd, 0x4e, 0xb3, 0x94, 0xd8, 0x6b, 0x14, 0x0b, 0x52, - 0x33, 0x63, 0x57, 0x04, 0x23, 0x72, 0x36, 0x11, 0x5b, 0x22, 0x44, 0x2a, 0x5b, 0x5f, 0x67, 0x2f, - 0xb0, 0x67, 0xda, 0x9b, 0x0c, 0xa4, 0xe4, 0xc4, 0xde, 0xdc, 0xee, 0x4f, 0xef, 0xc4, 0xef, 0x3b, - 0xe7, 0xc7, 0x23, 0xf2, 0x83, 0x04, 0xb0, 0x28, 0x44, 0x3a, 0x14, 0x45, 0xae, 0x72, 0x64, 0x47, - 0xaf, 0x7f, 0xc9, 0xa2, 0x57, 0x58, 0x4b, 0xee, 0x10, 0xec, 0x8b, 0xc0, 0x4f, 0x98, 0x52, 0x3c, - 0x5b, 0x48, 0xf4, 0x02, 0xec, 0xeb, 0x15, 0xcf, 0x6e, 0x70, 0x9a, 0x97, 0x99, 0x72, 0x1a, 0x27, - 0x8d, 0xd3, 0x5e, 0x0c, 0x46, 0x1a, 0x6b, 0xc5, 0x8d, 0xe0, 0xf1, 0x39, 0xa1, 0x0b, 0xa6, 0x36, - 0x2d, 0x81, 0x5a, 0xb2, 0x22, 0x63, 0x0a, 0x3d, 0x05, 0x6b, 0x99, 0x4b, 0x85, 0x09, 0xa5, 0x85, - 0x69, 0xb4, 0xe2, 0x8e, 0x16, 0x3c, 0x4a, 0x0b, 0xf4, 0x19, 0x74, 0x28, 0xbb, 0xad, 0xbc, 0x43, - 0xe3, 0xb5, 0x29, 0xbb, 0xd5, 0x96, 0xfb, 0x5b, 0x13, 0xfa, 0xbb, 0x48, 0xe4, 0x40, 0x9b, 0x65, - 0xe4, 0x7a, 0xc5, 0xa8, 0x01, 0x75, 0xe2, 0xcd, 0x12, 0x0d, 0xe0, 0xe8, 0x96, 0xd3, 0x1a, 0xa1, - 0x1f, 0xb5, 0x22, 0x38, 0x75, 0x8e, 0x2a, 0x45, 0x70, 0x8a, 0x5c, 0xe8, 0xae, 0x49, 0x56, 0xfe, - 0x4c, 0x52, 0x55, 0x16, 0xac, 0x70, 0x9a, 0xc6, 0xda, 0xd1, 0xf4, 0x0e, 0xa2, 0xc8, 0x69, 0x99, - 0x2a, 0xe7, 0xb8, 0x1a, 0xa7, 0x5e, 0xa2, 0xc7, 0xd0, 0x92, 0xac, 0xe0, 0x64, 0xe5, 0xb4, 0x8c, - 0x51, 0xaf, 0xd0, 0x73, 0xb0, 0x4b, 0xc9, 0xf0, 0xd8, 0x1f, 0xe3, 0x60, 0x1c, 0x3a, 0x6d, 0x33, - 0x97, 0x55, 0x4a, 0x36, 0xf6, 0xc7, 0xc1, 0x38, 0xd4, 0xaf, 0xaf, 0xfd, 0xf8, 0xd2, 0x9f, 0x26, - 0x4e, 0xc7, 0xb8, 0x9d, 0x52, 0x32, 0xb3, 0x46, 0xa7, 0x30, 0xd0, 0xe6, 0x64, 0xea, 0xe3, 0x37, - 0xc1, 0x4f, 0xdf, 0xcf, 0xbc, 0xd8, 0x77, 0x2c, 0x53, 0xd3, 0x2f, 0x25, 0x9b, 0x4c, 0xfd, 0x8d, - 0x8a, 0x5c, 0xe8, 0x6d, 0x2a, 0xc3, 0xd9, 0x55, 0x12, 0x38, 0x60, 0xca, 0xec, 0xaa, 0xcc, 0x48, - 0x9b, 0x51, 0x74, 0x4d, 0xec, 0xcd, 0x1d, 0xfb, 0x6e, 0x94, 0xc9, 0xd4, 0x8f, 0xbd, 0x39, 0xfa, - 0x14, 0xda, 0xda, 0xbf, 0x0a, 0x13, 0xa7, 0x6b, 0xbc, 0x56, 0x29, 0xd9, 0x55, 0x98, 0xa0, 0x67, - 0x00, 0xda, 0x48, 0x82, 0x78, 0xea, 0x5d, 0x38, 0xbd, 0xbb, 0xbe, 0x4a, 0x40, 0x3f, 0x40, 0xbf, - 0xc8, 0x28, 0x97, 0x58, 0xd6, 0x17, 0xe1, 0xf4, 0x4f, 0x1a, 0xa7, 0xf6, 0xe8, 0x8b, 0xe1, 0x56, - 0x62, 0x86, 0xfb, 0xaf, 0x3f, 0xee, 0x99, 0xd6, 0xbb, 0x2b, 0x0c, 0x61, 0x90, 0xd2, 0x14, 0xb3, - 0x74, 0x7d, 0x4f, 0x7b, 0xf0, 0xef, 0x69, 0xfd, 0x94, 0xa6, 0x41, 0xba, 0xde, 0xe8, 0xee, 0x1f, - 0x47, 0xd0, 0x9d, 0xf3, 0x33, 0x7e, 0xc7, 0xff, 0x1c, 0x2c, 0xca, 0x89, 0xdc, 0x0e, 0xc9, 0xbd, - 0xa0, 0x43, 0x51, 0xb0, 0xc5, 0x26, 0x26, 0x05, 0x5b, 0xa0, 0x11, 0x34, 0xd7, 0x39, 0x65, 0x26, - 0x27, 0xfd, 0xd1, 0xf3, 0x9d, 0x19, 0xb6, 0xc1, 0xc3, 0x30, 0xa7, 0x2c, 0x36, 0xb5, 0xfa, 0x1c, - 0x89, 0xc0, 0x52, 0x72, 0x5a, 0x67, 0xa8, 0x45, 0x44, 0x22, 0x39, 0x45, 0x1e, 0x58, 0xa4, 0x54, - 0x4b, 0x6c, 0x88, 0xc7, 0x86, 0xf8, 0xf2, 0xfd, 0x44, 0x2f, 0xf2, 0x4a, 0xb5, 0x34, 0xdc, 0x0e, - 0xa9, 0x9f, 0xf4, 0x55, 0x10, 0x81, 0xd3, 0x25, 0xc9, 0x32, 0x56, 0x45, 0xad, 0x17, 0x5b, 0x44, - 0x8c, 0x2b, 0x01, 0x7d, 0x02, 0x2d, 0x22, 0xb0, 0x90, 0x37, 0x26, 0x68, 0x56, 0x7c, 0x4c, 0x44, - 0x24, 0x6f, 0xd0, 0x09, 0x74, 0x89, 0xc0, 0x4b, 0x4e, 0x59, 0x35, 0x56, 0x95, 0x33, 0x20, 0x62, - 0xc2, 0x29, 0x33, 0xa3, 0xbd, 0x00, 0x3b, 0x5d, 0x71, 0x96, 0xa9, 0xaa, 0xc0, 0x32, 0xdd, 0x50, - 0x49, 0xa6, 0xe0, 0x19, 0xd4, 0x2b, 0x43, 0x07, 0xe3, 0x5b, 0x95, 0xa2, 0x77, 0xf8, 0x12, 0xfa, - 0x94, 0x9b, 0x53, 0xc4, 0x19, 0xfb, 0x75, 0x9d, 0x67, 0x75, 0xbc, 0x7a, 0xb5, 0x7a, 0x69, 0x44, - 0xf7, 0x2b, 0x68, 0x9a, 0xd7, 0x68, 0xc1, 0xa1, 0x17, 0x0d, 0x0e, 0x50, 0x1b, 0x8e, 0x92, 0xb7, - 0xde, 0xa0, 0x81, 0x1e, 0xc1, 0x83, 0xe4, 0xad, 0x87, 0xcf, 0xbc, 0xe9, 0xc5, 0xec, 0xc7, 0x20, - 0xc6, 0x5e, 0x34, 0x38, 0x74, 0x5f, 0x02, 0xdc, 0x1f, 0x02, 0xea, 0x42, 0x67, 0x1e, 0x79, 0x23, - 0x1c, 0x25, 0x6f, 0x06, 0x07, 0xa8, 0x03, 0xcd, 0x59, 0x14, 0x5c, 0x0e, 0x1a, 0x6e, 0x1b, 0x8e, - 0x83, 0xb5, 0x50, 0xef, 0x46, 0xbf, 0x37, 0xa1, 0x15, 0xbd, 0x9e, 0x5f, 0x46, 0xaf, 0x50, 0x08, - 0xce, 0x39, 0x53, 0x3e, 0x13, 0xab, 0xfc, 0x1d, 0xa3, 0x3b, 0x61, 0x41, 0x68, 0xe7, 0xc8, 0x4d, - 0xeb, 0x93, 0xa7, 0x1f, 0x08, 0x97, 0x7b, 0x80, 0x26, 0xf0, 0xa8, 0x62, 0x7d, 0x34, 0xe9, 0x0c, - 0x1e, 0x9e, 0x33, 0xf5, 0x97, 0xef, 0xd6, 0xff, 0xe0, 0xcc, 0xe0, 0x61, 0xf2, 0x37, 0xce, 0x87, - 0x7a, 0xfe, 0x09, 0xf8, 0x1d, 0xf4, 0xcf, 0x99, 0xda, 0xfe, 0xa6, 0xef, 0x9b, 0xca, 0xd9, 0xd1, - 0xb6, 0xaa, 0x2b, 0x42, 0xb2, 0x4b, 0x78, 0x6f, 0xf5, 0x93, 0x3d, 0x6c, 0xf7, 0x00, 0x7d, 0x03, - 0x90, 0xa8, 0x5c, 0x54, 0xb3, 0xed, 0xdd, 0x7f, 0x7f, 0xdf, 0xb7, 0x60, 0x27, 0x8a, 0x14, 0xea, - 0xbf, 0x36, 0x5e, 0xb7, 0xcc, 0x9f, 0xed, 0xeb, 0x3f, 0x03, 0x00, 0x00, 0xff, 0xff, 0x4a, 0x89, - 0x01, 0x89, 0xe7, 0x06, 0x00, 0x00, + // 850 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x55, 0x5d, 0x6f, 0xdb, 0x36, + 0x14, 0x8d, 0x13, 0x7f, 0xe9, 0xca, 0x76, 0x15, 0x76, 0xeb, 0xb4, 0x76, 0x6d, 0x03, 0xad, 0x03, + 0xf2, 0x30, 0x18, 0x68, 0xd6, 0xd7, 0x01, 0xd3, 0x2c, 0x25, 0xf6, 0x1a, 0xc5, 0x82, 0x54, 0xcf, + 0xd8, 0x13, 0xc1, 0x88, 0xac, 0x4d, 0xc4, 0xfa, 0x80, 0x44, 0x65, 0xeb, 0xfb, 0xfe, 0xe8, 0x1e, + 0xf6, 0x3f, 0x06, 0x52, 0xb2, 0x63, 0xb7, 0x6e, 0x32, 0x6c, 0x6f, 0xba, 0xe7, 0x9c, 0x7b, 0x78, + 0x45, 0x1e, 0x4a, 0x00, 0x8b, 0x3c, 0x8b, 0x86, 0x59, 0x9e, 0x8a, 0x14, 0xe9, 0xfe, 0x9b, 0xdf, + 0x13, 0xff, 0x35, 0x96, 0x90, 0x35, 0x04, 0xfd, 0xd2, 0x75, 0x42, 0x26, 0x04, 0x4f, 0x16, 0x05, + 0x7a, 0x09, 0xfa, 0xf5, 0x8a, 0x27, 0x37, 0x38, 0x4a, 0xcb, 0x44, 0x98, 0x8d, 0x93, 0xc6, 0x69, + 0x3f, 0x00, 0x05, 0x8d, 0x24, 0x62, 0xfd, 0xdd, 0x84, 0xc1, 0x05, 0xa1, 0x0b, 0x26, 0x36, 0x3d, + 0x26, 0x74, 0x58, 0x42, 0xae, 0x57, 0x8c, 0x2a, 0x7d, 0x37, 0x58, 0x97, 0xc8, 0x80, 0xa3, 0x5b, + 0x4e, 0xcd, 0xc3, 0x93, 0xc6, 0xa9, 0x16, 0xc8, 0x47, 0x89, 0x64, 0x9c, 0x9a, 0x47, 0x15, 0x92, + 0x71, 0x8a, 0x2c, 0xe8, 0xc5, 0x24, 0x29, 0xdf, 0x93, 0x48, 0x94, 0x39, 0xcb, 0xcd, 0xa6, 0xa2, + 0x76, 0x30, 0xb9, 0x42, 0x96, 0xa7, 0xb4, 0x8c, 0x84, 0xd9, 0x52, 0xf4, 0xba, 0x44, 0x4f, 0xa0, + 0x5d, 0xb0, 0x9c, 0x93, 0x95, 0xd9, 0x56, 0x44, 0x5d, 0xa1, 0x17, 0xa0, 0x97, 0x05, 0xc3, 0x23, + 0x67, 0x84, 0xdd, 0x91, 0x67, 0x76, 0xd4, 0x5c, 0x5a, 0x59, 0xb0, 0x91, 0x33, 0x72, 0x47, 0x1e, + 0x7a, 0x06, 0xb2, 0xc0, 0xc1, 0x95, 0x33, 0x09, 0xcd, 0xae, 0x62, 0xbb, 0x65, 0xc1, 0x54, 0x8d, + 0x4e, 0xc1, 0x90, 0xe4, 0x78, 0xe2, 0xe0, 0xb7, 0xee, 0x6f, 0x3f, 0x4f, 0xed, 0xc0, 0x31, 0x35, + 0xa5, 0x19, 0x94, 0x05, 0x1b, 0x4f, 0x9c, 0x35, 0x8a, 0x2c, 0xe8, 0xaf, 0x95, 0xde, 0x74, 0x16, + 0xba, 0x26, 0x28, 0x99, 0x5e, 0xc9, 0x14, 0xb4, 0x1e, 0x45, 0x6a, 0x02, 0x7b, 0x6e, 0xea, 0x9b, + 0x51, 0xc6, 0x13, 0x27, 0xb0, 0xe7, 0xe8, 0x2b, 0xe8, 0x48, 0x7e, 0xe6, 0x85, 0x66, 0x4f, 0x71, + 0xed, 0xb2, 0x60, 0x33, 0x2f, 0x44, 0xcf, 0x01, 0x24, 0x11, 0xba, 0xc1, 0xc4, 0xbe, 0x34, 0xfb, + 0x9b, 0xbe, 0x0a, 0x40, 0xbf, 0xc0, 0x20, 0x4f, 0x28, 0x2f, 0x70, 0x51, 0x1f, 0x84, 0x39, 0x38, + 0x69, 0x9c, 0xea, 0x67, 0xdf, 0x0e, 0xb7, 0xce, 0x77, 0xb8, 0x7b, 0x56, 0xae, 0x58, 0xb2, 0x3c, + 0x61, 0x22, 0xe8, 0xab, 0xd6, 0xcd, 0x11, 0x7a, 0x60, 0x44, 0x34, 0xc2, 0x2c, 0x8a, 0xef, 0xdc, + 0x1e, 0xfd, 0x7b, 0xb7, 0x41, 0x44, 0x23, 0x37, 0x8a, 0x37, 0x76, 0x36, 0xf4, 0xca, 0x78, 0x6b, + 0x30, 0x43, 0x59, 0xbd, 0xb8, 0xc7, 0x6a, 0xe6, 0x85, 0x81, 0x5e, 0xc6, 0x9b, 0x89, 0x2c, 0x1f, + 0x9e, 0xec, 0x5f, 0x4c, 0x1e, 0xdd, 0x32, 0x2d, 0x04, 0x26, 0x94, 0xe6, 0x2a, 0x70, 0x5a, 0xd0, + 0x95, 0x80, 0x4d, 0x69, 0x8e, 0xbe, 0x86, 0x2e, 0x65, 0xb7, 0x15, 0x57, 0xc5, 0xae, 0x43, 0xd9, + 0xad, 0xa4, 0xac, 0x1f, 0xe1, 0xf8, 0x93, 0x35, 0xd1, 0x17, 0xd0, 0x8a, 0x68, 0x9e, 0xc6, 0x75, + 0x72, 0xab, 0x02, 0x21, 0x68, 0xbe, 0xe7, 0x2b, 0x56, 0x3b, 0xa8, 0x67, 0xeb, 0xaf, 0x23, 0xe8, + 0xcd, 0xf9, 0x39, 0xdf, 0xbc, 0xe4, 0x37, 0xa0, 0x51, 0x4e, 0x8a, 0xed, 0xe0, 0xdf, 0x01, 0x32, + 0xe8, 0x39, 0x5b, 0xac, 0xa3, 0x9f, 0xb3, 0x05, 0x3a, 0x83, 0x66, 0x9c, 0x52, 0xa6, 0xb2, 0x3f, + 0xf8, 0x68, 0x33, 0xb6, 0x8d, 0x87, 0x5e, 0x4a, 0x59, 0xa0, 0xb4, 0x32, 0x1b, 0x24, 0xc3, 0x45, + 0xc1, 0x69, 0x7d, 0x2f, 0xda, 0x24, 0x0b, 0x0b, 0x4e, 0x91, 0x0d, 0x1a, 0x29, 0xc5, 0x12, 0x2b, + 0xc7, 0x96, 0x72, 0x7c, 0xf5, 0x79, 0x47, 0xdb, 0xb7, 0x4b, 0xb1, 0x54, 0xbe, 0x5d, 0x52, 0x3f, + 0xc9, 0x78, 0x91, 0x0c, 0x47, 0x4b, 0x92, 0x24, 0xac, 0xba, 0x3e, 0xfd, 0x40, 0x23, 0xd9, 0xa8, + 0x02, 0xd0, 0x97, 0xd0, 0x26, 0x19, 0xce, 0x8a, 0x1b, 0x75, 0x79, 0xb4, 0xa0, 0x45, 0x32, 0xbf, + 0xb8, 0x41, 0x27, 0xd0, 0x23, 0x19, 0x5e, 0x72, 0xca, 0xaa, 0xb1, 0xaa, 0xbb, 0x03, 0x24, 0x1b, + 0x73, 0xca, 0xd4, 0x68, 0x2f, 0x41, 0x8f, 0x56, 0x9c, 0x25, 0xa2, 0x12, 0x68, 0xaa, 0x1b, 0x2a, + 0x48, 0x09, 0x9e, 0x43, 0x5d, 0x29, 0x77, 0x50, 0xbc, 0x56, 0x21, 0x72, 0x85, 0xef, 0x60, 0x40, + 0xb9, 0xda, 0x45, 0x9c, 0xb0, 0x3f, 0xe2, 0x34, 0xa9, 0xaf, 0x4c, 0xbf, 0x46, 0xaf, 0x14, 0x68, + 0x7d, 0x0f, 0x4d, 0xf5, 0x1a, 0x6d, 0x38, 0xb4, 0x7d, 0xe3, 0x00, 0x75, 0xe0, 0x28, 0x7c, 0x67, + 0x1b, 0x0d, 0xf4, 0x18, 0x1e, 0x85, 0xef, 0x6c, 0x7c, 0x6e, 0x4f, 0x2e, 0xa7, 0xbf, 0xba, 0x01, + 0xb6, 0x7d, 0xe3, 0xd0, 0x7a, 0x05, 0x70, 0xb7, 0x09, 0xa8, 0x07, 0xdd, 0xb9, 0x6f, 0x9f, 0x61, + 0x3f, 0x7c, 0x6b, 0x1c, 0xa0, 0x2e, 0x34, 0xa7, 0xbe, 0x7b, 0x65, 0x34, 0xac, 0x0e, 0xb4, 0xdc, + 0x38, 0x13, 0x1f, 0xce, 0xfe, 0x6c, 0x42, 0xdb, 0x7f, 0x33, 0xbf, 0xf2, 0x5f, 0x23, 0x0f, 0xcc, + 0x0b, 0x26, 0x1c, 0x96, 0xad, 0xd2, 0x0f, 0x8c, 0xee, 0x24, 0x08, 0xa1, 0x9d, 0x2d, 0x57, 0xad, + 0x4f, 0x9f, 0xdd, 0x93, 0x72, 0xeb, 0x00, 0x8d, 0xe1, 0x71, 0xe5, 0xf5, 0xbf, 0x9d, 0xce, 0xe1, + 0xf8, 0x82, 0x89, 0x8f, 0xbe, 0xc5, 0xff, 0xc1, 0x67, 0x0a, 0xc7, 0xe1, 0x27, 0x3e, 0xf7, 0xf5, + 0x3c, 0x64, 0xf8, 0x13, 0x0c, 0x2e, 0x98, 0xd8, 0xfe, 0xab, 0xec, 0x9b, 0xca, 0xdc, 0xc1, 0xb6, + 0xd4, 0x95, 0x43, 0xb8, 0xeb, 0xf0, 0x59, 0xf5, 0xd3, 0x3d, 0xde, 0xd6, 0x01, 0x72, 0xa0, 0xe7, + 0xc9, 0xff, 0xd5, 0xcc, 0x0b, 0xcf, 0xf9, 0x8a, 0xa1, 0x07, 0xbe, 0x3d, 0xfb, 0x5d, 0xae, 0xdb, + 0xea, 0x87, 0xf9, 0xc3, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x56, 0x2c, 0x60, 0xd5, 0x3e, 0x07, + 0x00, 0x00, } diff --git a/proto/grpc.proto b/proto/grpc.proto index 6f660cd..53e21ac 100644 --- a/proto/grpc.proto +++ b/proto/grpc.proto @@ -9,19 +9,13 @@ service P4WNP1 { rpc SetGadgetSettings (GadgetSettings) returns (GadgetSettings) {} rpc GetLEDSettings (Empty) returns (LEDSettings) {} rpc SetLEDSettings (LEDSettings) returns (Empty) {} - rpc StopGadget (Empty) returns (Empty) {} - rpc StartGadget (Empty) returns (Empty) {} + rpc MountUMSFile (GadgetSettingsUMS) returns (Empty) {} } message LEDSettings { uint32 blink_count = 1; } -message GadgetSettingsEthernet { - string host_addr = 1; - string dev_addr = 2; -} - message GadgetSettings { bool enabled = 1; string vid = 2; @@ -38,7 +32,17 @@ message GadgetSettings { bool use_SERIAL = 13; GadgetSettingsEthernet rndis_settings = 14; GadgetSettingsEthernet cdc_ecm_settings = 15; + GadgetSettingsUMS ums_settings = 16; +} +message GadgetSettingsEthernet { + string host_addr = 1; + string dev_addr = 2; +} + +message GadgetSettingsUMS { + bool cdrom = 1; + string file = 2; } message WiFiSettings { diff --git a/service/rpc.go b/service/rpc.go index 9f707e6..c8a1b5a 100644 --- a/service/rpc.go +++ b/service/rpc.go @@ -15,6 +15,12 @@ import ( type server struct {} +func (s *server) MountUMSFile(ctx context.Context, gsu *pb.GadgetSettingsUMS) (*pb.Empty, error) { + log.Printf("Trying to mount iamge `%s` to UMS ...", gsu.File) + err := MountUMSFile(gsu.File) + return nil, err +} + func (s *server) GetDeployedGadgetSetting(ctx context.Context, e *pb.Empty) (gs *pb.GadgetSettings, err error) { gs, err = ParseGadgetState(USB_GADGET_NAME) @@ -72,60 +78,6 @@ func (s *server) SetLEDSettings(ctx context.Context, ls *pb.LEDSettings) (*pb.Em return &pb.Empty{}, nil } -func (s *server) StopGadget(context.Context, *pb.Empty) (*pb.Empty, error) { - panic("implement me") -} - -func (s *server) StartGadget(context.Context, *pb.Empty) (*pb.Empty, error) { - panic("implement me") -} - -/* -//Attach handler function implementing the "GetGadgetSettings" interface to server -func (s *server) GetGadgetSettings(context.Context, *pb.Empty) (usbset *pb.GadgetSettings, err error) { - usbset, err = ParseGadgetState(USB_GADGET_NAME) - - if err == nil { - j_usbset, _ := json.Marshal(usbset) - log.Printf("Gadget settings requested %v", string(j_usbset)) - } else { - log.Printf("Error parsing current gadget config: %v", err) - } - - - return usbset, err -} - - - -//Attach handler function implementing the "SetGadgetSettings" interface to server - - -func (s *server) SetGadgetSettings(context.Context, *pb.GadgetSettings) (*pb.Error, error) { - return &pb.Error{Err: 0}, nil -} - -//Attach handler function implementing the "StartGadget" interface to server -func (s *server) StartGadget(context.Context, *pb.Empty) (*pb.Error, error) { - return &pb.Error{Err: 0}, nil -} - -//Attach handler function implementing the "StopGadget" interface to server -func (s *server) StopGadget(context.Context, *pb.Empty) (*pb.Error, error) { - return &pb.Error{Err: 0}, nil -} - -func (s *server) GetLEDSettings(context.Context, *pb.Empty) (*pb.LEDSettings, error) { - led_settings := &pb.LEDSettings{} - return led_settings, nil -} - -func (s *server) SetLEDSettings(ctx context.Context, ledSettings *pb.LEDSettings) (rpcerr *pb.Error, err error) { - log.Printf("SetLEDSettings %+v", ledSettings) - setLed(*ledSettings) - return &pb.Error{Err: 0}, nil -} -*/ func StartRpcServer(host string, port string) { listen_address := host + ":" + port diff --git a/service/usb.go b/service/usb.go index 0de1001..eafce7e 100644 --- a/service/usb.go +++ b/service/usb.go @@ -11,9 +11,19 @@ import ( pb "../proto" "time" "fmt" + "net" ) const ( + USB_EP_USAGE_HID_RAW = 1 + USB_EP_USAGE_HID_KEYBOARD = 1 + USB_EP_USAGE_HID_MOUSE = 1 + USB_EP_USAGE_RNDIS = 2 + USB_EP_USAGE_CDC_ECM = 2 + USB_EP_USAGE_CDC_SERIAL = 2 //ToDo: check, taken from docs + USB_EP_USAGE_UMS = 2 //ToDo check, taken from docs + USB_EP_USAGE_MAX = 7 + USB_GADGET_NAME = "mame82_gadget" USB_GADGET_DIR_BASE = "/sys/kernel/config/usb_gadget" USB_GADGET_DIR = USB_GADGET_DIR_BASE + "/" + USB_GADGET_NAME @@ -31,11 +41,6 @@ const ( USB_CONFIGURATION_MaxPower = "250" USB_CONFIGURATION_bmAttributes = "0x80" //should be 0x03 for USB_OTG_SRP | USB_OTG_HNP - /* - //RNDIS function constants - USB_FUNCTION_RNDIS_DEFAULT_host_addr = "42:63:65:12:34:56" - USB_FUNCTION_RNDIS_DEFAULT_dev_addr = "42:63:65:56:34:12" - */ //OS descriptors for RNDIS composite function on Windows USB_FUNCTION_RNDIS_os_desc_use = "1" USB_FUNCTION_RNDIS_os_desc_b_vendor_code = "0xbc" @@ -43,12 +48,6 @@ const ( USB_FUNCTION_RNDIS_os_desc_interface_compatible_id = "RNDIS" USB_FUNCTION_RNDIS_os_desc_interface_sub_compatible_id = "5162001" - /* - //CDC ECM function constants - USB_FUNCTION_CDC_ECM_DEFAULT_host_addr = "42:63:66:12:34:56" - USB_FUNCTION_CDC_ECM_DEFAULT_dev_addr = "42:63:66:56:34:12" - */ - //HID function, keyboard constants USB_FUNCTION_HID_KEYBOARD_protocol = "1" USB_FUNCTION_HID_KEYBOARD_subclass = "1" @@ -73,20 +72,52 @@ const ( ) var ( - DefaultGadgetSettings pb.GadgetSettings = GetDefaultGadgetSettings() - GadgetSettingsState pb.GadgetSettings = GetDefaultGadgetSettings() + defaultGadgetSettings pb.GadgetSettings = GetDefaultGadgetSettings() //ToDo: Read defaults from external file, failover to hardcoded on validation fail (consumin to many EPs) + GadgetSettingsState pb.GadgetSettings = GetDefaultGadgetSettings() ) func ValidateGadgetSetting(gs pb.GadgetSettings) error { /* ToDo: validations - - check host_addr/dev_addr of RNDIS + CDC ECM to be valid MAC addresses via regex + - Done: check host_addr/dev_addr of RNDIS + CDC ECM to be valid MAC addresses via regex - check host_addr/dev_addr of RNDIS + CDC ECM for duplicates - - check EP consumption to be not more than 7 (ECM 2 EP, RNDIS 2 EP, HID Mouse 1 EP, HID Keyboard 1 EP, HID Raw 1 EP, Serial 2 EP ??, UMS ??) + - check EP consumption to be not more than 7 (ECM 2 EP, RNDIS 2 EP, HID Mouse 1 EP, HID Keyboard 1 EP, HID Raw 1 EP, Serial 2 EP ??, UMS 2 EP ?) - check serial, product, Manufacturer to not be empty - check Pid, Vid with regex (Note: we don't check if Vid+Pid have been used for another composite function setup, yet) - If the gadget is enabled, at least one function has to be enabled */ + log.Println("Validating gadget settings ...") + + if gs.Use_RNDIS { + _, err := net.ParseMAC(gs.RndisSettings.DevAddr) + if err != nil { return errors.New(fmt.Sprintf("Validation Error RNDIS DeviceAddress: %v", err))} + + _, err = net.ParseMAC(gs.RndisSettings.HostAddr) + if err != nil { return errors.New(fmt.Sprintf("Validation Error RNDIS HostAddress: %v", err))} + } + + if gs.Use_CDC_ECM { + _, err := net.ParseMAC(gs.CdcEcmSettings.DevAddr) + if err != nil { return errors.New(fmt.Sprintf("Validation Error CDC ECM DeviceAddress: %v", err))} + + _, err = net.ParseMAC(gs.CdcEcmSettings.HostAddr) + if err != nil { return errors.New(fmt.Sprintf("Validation Error CDC ECM HostAddress: %v", err))} + } + + //check endpoint consumption + sum_ep := 0 + if gs.Use_RNDIS { sum_ep += USB_EP_USAGE_RNDIS } + if gs.Use_CDC_ECM { sum_ep += USB_EP_USAGE_CDC_ECM } + if gs.Use_UMS { sum_ep += USB_EP_USAGE_UMS } + if gs.Use_HID_MOUSE { sum_ep += USB_EP_USAGE_HID_MOUSE } + if gs.Use_HID_RAW { sum_ep += USB_EP_USAGE_HID_RAW } + if gs.Use_HID_KEYBOARD { sum_ep += USB_EP_USAGE_HID_KEYBOARD } + if gs.Use_SERIAL { sum_ep+= USB_EP_USAGE_CDC_SERIAL } + + strConsumption := fmt.Sprintf("Gadget Settings consume %v out of %v available USB Endpoints\n", sum_ep, USB_EP_USAGE_MAX) + log.Print(strConsumption) + if sum_ep > USB_EP_USAGE_MAX { return errors.New(strConsumption)} + return nil } @@ -132,7 +163,7 @@ func pollForUSBEthernet(timeout time.Duration) error { } func InitDefaultGadgetSettings() error { - return DeployGadgetSettings(DefaultGadgetSettings) + return DeployGadgetSettings(defaultGadgetSettings) } func GetDefaultGadgetSettings() (res pb.GadgetSettings) { @@ -158,12 +189,16 @@ func GetDefaultGadgetSettings() (res pb.GadgetSettings) { HostAddr: "42:63:66:12:34:56", DevAddr: "42:63:66:56:34:12", }, + UmsSettings: &pb.GadgetSettingsUMS{ + File:"", //we don't supply an image file, which is no problem as it could be applied later on (removable media) + Cdrom:false, //By default we don't emulate a CD drive, but a flashdrive + }, } return res } -//depends on `bash`, `grep` and `lsmod` binary +//depends on `lsmod` binary func CheckLibComposite() error { log.Printf("Checking for libcomposite...") out, err := exec.Command("lsmod").Output() @@ -309,11 +344,35 @@ func ParseGadgetState(gadgetName string) (result *pb.GadgetSettings, err error) result.Use_HID_MOUSE = true } - //USB HID RAW + //USB HID Raw if _, err1 := os.Stat(gadget_dir+"/configs/c.1/"+USB_FUNCTION_HID_RAW_name); !os.IsNotExist(err1) { result.Use_HID_RAW = true } + //USB Mass Storage + if _, err1 := os.Stat(gadget_dir+"/configs/c.1/mass_storage.ms1"); !os.IsNotExist(err1) { + result.Use_UMS = true + result.UmsSettings = &pb.GadgetSettingsUMS{} + + //Check if running as CD-Rom + if res, err := ioutil.ReadFile(gadget_dir + "/functions/mass_storage.ms1/lun.0/cdrom"); err != nil { + err1 := errors.New(fmt.Sprintf("Gadget %s error reading USB Mass Storage cdrom emulation state", gadgetName)) + return nil, err1 + } else { + if strings.HasPrefix(string(res), "1") { + result.UmsSettings.Cdrom = true + } //else branche unneeded, as false is default + } + + //Check name of backing file + if res, err := ioutil.ReadFile(gadget_dir + "/functions/mass_storage.ms1/lun.0/file"); err != nil { + err1 := errors.New(fmt.Sprintf("Gadget %s error reading USB Mass Storage image file setting", gadgetName)) + return nil, err1 + } else { + result.UmsSettings.File = strings.TrimSuffix(string(res), "\000\n") + } + } + //check if UDC is set (Gadget enabled) udc_name, _ := getUDCName() @@ -322,7 +381,7 @@ func ParseGadgetState(gadgetName string) (result *pb.GadgetSettings, err error) return nil, err1 } else { udc_name_set := strings.TrimSuffix(string(res), "\n") - log.Printf("UDC test: udc_name_set %s, udc_name %s", udc_name_set, udc_name) + //log.Printf("UDC test: udc_name_set %s, udc_name %s", udc_name_set, udc_name) if udc_name == udc_name_set { result.Enabled = true } @@ -332,6 +391,17 @@ func ParseGadgetState(gadgetName string) (result *pb.GadgetSettings, err error) } +// This command is working on the active gadget directly, so changes aren't refelcted back +// to the GadgetSettingsState +func MountUMSFile(filename string) error { + funcdir := USB_GADGET_DIR + "/functions/mass_storage.ms1" + err := ioutil.WriteFile(funcdir+"/lun.0/file", []byte(filename), os.ModePerm) + if err != nil { + return errors.New(fmt.Sprintf("Settings backing file for USB Mass Storage failed: %v", err)) + } + return nil +} + func DeployGadgetSettings(settings pb.GadgetSettings) error { var usesUSBEthernet bool @@ -493,6 +563,33 @@ func DeployGadgetSettings(settings pb.GadgetSettings) error { } } + if settings.Use_UMS { + log.Printf("... creating USB Mass Storage device function") + funcdir := USB_GADGET_DIR + "/functions/mass_storage.ms1" + os.Mkdir(funcdir, os.ModePerm) //create HID function for mouse + + ioutil.WriteFile(funcdir+"/stall", []byte("1"), os.ModePerm) // Allow bulk Endpoints + if settings.UmsSettings.Cdrom { + ioutil.WriteFile(funcdir+"/lun.0/cdrom", []byte("1"), os.ModePerm) // CD-Rom + } else { + ioutil.WriteFile(funcdir+"/lun.0/cdrom", []byte("0"), os.ModePerm) // Writable flashdrive + } + + ioutil.WriteFile(funcdir+"/lun.0/ro", []byte("0"), os.ModePerm) // Don't restrict to read-only (is implied by cdrom=1 if needed, but causes issues on backend FS if enabled) + + // enable Force Unit Access (FUA) to make Windows write synchronously + // this is slow, but unplugging the stick without unmounting works + ioutil.WriteFile(funcdir+"/lun.0/nofua", []byte("0"), os.ModePerm) // Don't restrict to read-only (is implied by cdrom=1 if needed, but causes issues on backend FS if enabled) + + //Provide the backing image + ioutil.WriteFile(funcdir+"/lun.0/file", []byte(settings.UmsSettings.File), os.ModePerm) // Set backing file (or block device) for USB Mass Storage + + err := os.Symlink(funcdir, USB_GADGET_DIR+"/configs/c.1/"+"mass_storage.ms1") + if err != nil { + log.Println(err) + } + } + //get UDC driver name and bind to gadget if settings.Enabled { udc_name, err := getUDCName()