mirror of
https://github.com/RoganDawes/P4wnP1_aloa.git
synced 2025-03-17 21:31:56 +01:00
Added USB gadget configuration to CLI, ToDo: validation (avoid kernel panic by consuming too many endpoints); auto-deploy by default
This commit is contained in:
parent
064ac0edb7
commit
b7092ebf6b
@ -5,11 +5,13 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
"log"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
)
|
||||
|
||||
//Empty settings used to store cobra flags
|
||||
var (
|
||||
//tmpGadgetSettings = pb.GadgetSettings{CdcEcmSettings:&pb.GadgetSettingsEthernet{},RndisSettings:&pb.GadgetSettingsEthernet{}}
|
||||
tmpDisableGadget bool = false
|
||||
tmpUseHIDKeyboard uint8 = 0
|
||||
tmpUseHIDMouse uint8 = 0
|
||||
tmpUseHIDRaw uint8 = 0
|
||||
@ -19,6 +21,12 @@ var (
|
||||
tmpUseUMS uint8 = 0
|
||||
)
|
||||
|
||||
func init(){
|
||||
//Configure spew for struct deep printing (disable using printer interface for gRPC structs)
|
||||
spew.Config.Indent="\t"
|
||||
spew.Config.DisableMethods = true
|
||||
spew.Config.DisablePointerAddresses = true
|
||||
}
|
||||
|
||||
// usbCmd represents the usb command
|
||||
var usbCmd = &cobra.Command{
|
||||
@ -33,6 +41,20 @@ var usbGetCmd = &cobra.Command{
|
||||
Run: cobraUsbGet,
|
||||
}
|
||||
|
||||
var usbGetDeployedCmd = &cobra.Command{
|
||||
Use: "deployed",
|
||||
Short: "Get deployed USB Gadget settings (the currently running configuration for the kernel module)",
|
||||
Long: ``,
|
||||
Run: cobraUsbGetDeployed,
|
||||
}
|
||||
|
||||
var usbSetDeployeCmd = &cobra.Command{
|
||||
Use: "deploy",
|
||||
Short: "Deployed the USB Gadget settings (as running configuration for the kernel module)",
|
||||
Long: ``,
|
||||
Run: cobraUsbDeploySettings,
|
||||
}
|
||||
|
||||
var usbSetCmd = &cobra.Command{
|
||||
Use: "set",
|
||||
Short: "set USB Gadget settings",
|
||||
@ -47,7 +69,15 @@ func cobraUsbSet(cmd *cobra.Command, args []string) {
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("USB Gadget Settings retreived: %+v\n", gs)
|
||||
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)")
|
||||
gs.Enabled = false
|
||||
} else {
|
||||
fmt.Println("Gadget set to enabled (will be usable after deployment)")
|
||||
gs.Enabled = true
|
||||
}
|
||||
|
||||
if (cmd.Flags().Lookup("rndis").Changed) {
|
||||
if tmpUseRNDIS == 0 {
|
||||
@ -60,7 +90,7 @@ func cobraUsbSet(cmd *cobra.Command, args []string) {
|
||||
}
|
||||
|
||||
if (cmd.Flags().Lookup("cdc-ecm").Changed) {
|
||||
if tmpUseRNDIS == 0 {
|
||||
if tmpUseECM == 0 {
|
||||
fmt.Println("Disabeling CDC ECM")
|
||||
gs.Use_CDC_ECM = false
|
||||
} else {
|
||||
@ -70,7 +100,7 @@ func cobraUsbSet(cmd *cobra.Command, args []string) {
|
||||
}
|
||||
|
||||
if (cmd.Flags().Lookup("serial").Changed) {
|
||||
if tmpUseRNDIS == 0 {
|
||||
if tmpUseSerial == 0 {
|
||||
fmt.Println("Disabeling Serial")
|
||||
gs.Use_SERIAL = false
|
||||
} else {
|
||||
@ -80,7 +110,7 @@ func cobraUsbSet(cmd *cobra.Command, args []string) {
|
||||
}
|
||||
|
||||
if (cmd.Flags().Lookup("hid-keyboard").Changed) {
|
||||
if tmpUseRNDIS == 0 {
|
||||
if tmpUseHIDKeyboard == 0 {
|
||||
fmt.Println("Disabeling HID keyboard")
|
||||
gs.Use_HID_KEYBOARD = false
|
||||
} else {
|
||||
@ -89,8 +119,38 @@ func cobraUsbSet(cmd *cobra.Command, args []string) {
|
||||
}
|
||||
}
|
||||
|
||||
if (cmd.Flags().Lookup("hid-mouse").Changed) {
|
||||
if tmpUseHIDMouse == 0 {
|
||||
fmt.Println("Disabeling HID mouse")
|
||||
gs.Use_HID_MOUSE = false
|
||||
} else {
|
||||
fmt.Println("Enabeling HID mouse")
|
||||
gs.Use_HID_MOUSE = true
|
||||
}
|
||||
}
|
||||
|
||||
//ToDo: Implement the rest (HID, UMS etc.)
|
||||
if (cmd.Flags().Lookup("hid-raw").Changed) {
|
||||
if tmpUseHIDRaw == 0 {
|
||||
fmt.Println("Disabeling HID raw device")
|
||||
gs.Use_HID_RAW = false
|
||||
} else {
|
||||
fmt.Println("Enabeling HID raw device")
|
||||
gs.Use_HID_RAW = true
|
||||
}
|
||||
}
|
||||
|
||||
if (cmd.Flags().Lookup("ums").Changed) {
|
||||
if tmpUseUMS == 0 {
|
||||
fmt.Println("Disabeling USB Mass Storage")
|
||||
gs.Use_UMS = false
|
||||
} else {
|
||||
fmt.Println("Enabeling USB Mass Storage")
|
||||
gs.Use_UMS = true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//ToDo: Implement detailed UMS settings
|
||||
|
||||
//Try to set the change config
|
||||
err = ClientSetGadgetSettings(StrRemoteHost, StrRemotePort, *gs)
|
||||
@ -104,13 +164,32 @@ func cobraUsbSet(cmd *cobra.Command, args []string) {
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("USB Gadget Settings set: %+v\n", gs)
|
||||
fmt.Printf("New USB Gadget Settings:\n%s", spew.Sdump(gs))
|
||||
return
|
||||
}
|
||||
|
||||
func cobraUsbGet(cmd *cobra.Command, args []string) {
|
||||
if gs, err := ClientGetGadgetSettings(StrRemoteHost, StrRemotePort); err == nil {
|
||||
fmt.Printf("USB Gadget Settings: %+v\n", gs)
|
||||
fmt.Printf("USB Gadget Settings:\n%s", spew.Sdump(gs))
|
||||
} else {
|
||||
log.Println(err)
|
||||
}
|
||||
}
|
||||
|
||||
func cobraUsbDeploySettings(cmd *cobra.Command, args []string) {
|
||||
|
||||
if gs, err := ClientDeployGadgetSettings(StrRemoteHost, StrRemotePort); err != nil {
|
||||
fmt.Printf("Error deploying Gadget Settings: %v\nReverted to:\n%s", err, spew.Sdump(gs))
|
||||
} else {
|
||||
fmt.Printf("Successfully deployed:\n%s", spew.Sdump(gs))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
func cobraUsbGetDeployed(cmd *cobra.Command, args []string) {
|
||||
if gs, err := ClientGetDeployedGadgetSettings(StrRemoteHost, StrRemotePort); err == nil {
|
||||
fmt.Printf("Deployed USB Gadget Settings:\n%s", spew.Sdump(gs))
|
||||
} else {
|
||||
log.Println(err)
|
||||
}
|
||||
@ -120,18 +199,10 @@ func init() {
|
||||
rootCmd.AddCommand(usbCmd)
|
||||
usbCmd.AddCommand(usbGetCmd)
|
||||
usbCmd.AddCommand(usbSetCmd)
|
||||
usbGetCmd.AddCommand(usbGetDeployedCmd)
|
||||
usbSetCmd.AddCommand(usbSetDeployeCmd)
|
||||
|
||||
// Here you will define your flags and configuration settings.
|
||||
|
||||
// Cobra supports Persistent Flags which will work for this command
|
||||
// and all subcommands, e.g.:
|
||||
// usbCmd.PersistentFlags().String("foo", "", "A help for foo")
|
||||
|
||||
// Cobra supports local flags which will only run when this command
|
||||
// is called directly, e.g.:
|
||||
// usbCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
|
||||
|
||||
|
||||
usbSetCmd.Flags().BoolVarP(&tmpDisableGadget, "disabled","d", false, "If this option is set, the gadget stays inactive after deployment (not bound to UDC)")
|
||||
usbSetCmd.Flags().Uint8VarP(&tmpUseRNDIS, "rndis", "n",0,"Use the RNDIS gadget function (0: disable, 1..n: enable)")
|
||||
usbSetCmd.Flags().Uint8VarP(&tmpUseECM, "cdc-ecm", "e",0,"Use the CDC ECM gadget function (0: disable, 1..n: enable)")
|
||||
usbSetCmd.Flags().Uint8VarP(&tmpUseSerial, "serial", "s",0,"Use the SERIAL gadget function (0: disable, 1..n: enable)")
|
||||
|
@ -56,6 +56,40 @@ func ClientGetGadgetSettings(host string, port string) (gs *pb.GadgetSettings, e
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
gs, err = client.DeployGadgetSetting(ctx, &pb.Empty{})
|
||||
if err != nil {
|
||||
log.Printf("Error deploying current USB Gadget Settings: %+v", err)
|
||||
//We have an error case, thus gs isn't submitted by the gRPC server (even if the value is provided)
|
||||
//in case of an error `gs`should reflect the Gadget Settings which are deployed, now that deployment of the
|
||||
//new settings failed. So we fetch the result manually
|
||||
gs, _ = client.GetDeployedGadgetSetting(ctx, &pb.Empty{}) //We ignore a new error this time, if it occures `gs` will be nil
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func ClientGetDeployedGadgetSettings(host string, port string) (gs *pb.GadgetSettings, err error) {
|
||||
conn, client, ctx, cancel, err := ClientConnectServer(host, port)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
gs, err = client.GetDeployedGadgetSetting(ctx, &pb.Empty{})
|
||||
if err != nil {
|
||||
log.Printf("Error getting USB Gadget Settings count: %+v", err)
|
||||
}
|
||||
|
@ -30,6 +30,10 @@ func (s *server) GetDeployedGadgetSetting(ctx context.Context, e *pb.Empty) (gs
|
||||
|
||||
func (s *server) DeployGadgetSetting(context.Context, *pb.Empty) (gs *pb.GadgetSettings, err error) {
|
||||
gs_backup,_ := ParseGadgetState(USB_GADGET_NAME)
|
||||
|
||||
//ToDo: Former gadgets are destroyed without testing if there're changes, this should be aborted if GadgetSettingsState == GetDeployedGadgetSettings()
|
||||
DestroyGadget(USB_GADGET_NAME)
|
||||
|
||||
errg := DeployGadgetSettings(GadgetSettingsState)
|
||||
err = nil
|
||||
if errg != nil {
|
||||
|
@ -79,7 +79,7 @@ var (
|
||||
|
||||
func ValidateGadgetSetting(gs pb.GadgetSettings) error {
|
||||
/* ToDo: validations
|
||||
- check host_addr/dev_addr of RNDIS + CDC ECM to be valid MAC adresses via regex
|
||||
- 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 serial, product, Manufacturer to not be empty
|
||||
@ -200,8 +200,6 @@ func getUDCName() (string, error) {
|
||||
func ParseGadgetState(gadgetName string) (result *pb.GadgetSettings, err error) {
|
||||
err = nil
|
||||
result = &pb.GadgetSettings{}
|
||||
result.CdcEcmSettings = &pb.GadgetSettingsEthernet{}
|
||||
result.RndisSettings = &pb.GadgetSettingsEthernet{}
|
||||
|
||||
//gadget_root := "./test"
|
||||
gadget_dir := USB_GADGET_DIR_BASE + "/" + gadgetName
|
||||
@ -256,6 +254,8 @@ func ParseGadgetState(gadgetName string) (result *pb.GadgetSettings, err error)
|
||||
if _, err1 := os.Stat(gadget_dir+"/configs/c.1/rndis.usb0"); !os.IsNotExist(err1) {
|
||||
result.Use_RNDIS = true
|
||||
|
||||
result.RndisSettings = &pb.GadgetSettingsEthernet{}
|
||||
|
||||
if res, err := ioutil.ReadFile(gadget_dir + "/functions/rndis.usb0/host_addr"); err != nil {
|
||||
err1 := errors.New(fmt.Sprintf("Gadget %s error reading RNDIS host_addr", gadgetName))
|
||||
return nil, err1
|
||||
@ -275,6 +275,8 @@ func ParseGadgetState(gadgetName string) (result *pb.GadgetSettings, err error)
|
||||
if _, err1 := os.Stat(gadget_dir+"/configs/c.1/ecm.usb1"); !os.IsNotExist(err1) {
|
||||
result.Use_CDC_ECM = true
|
||||
|
||||
result.CdcEcmSettings = &pb.GadgetSettingsEthernet{}
|
||||
|
||||
if res, err := ioutil.ReadFile(gadget_dir + "/functions/ecm.usb1/host_addr"); err != nil {
|
||||
err1 := errors.New(fmt.Sprintf("Gadget %s error reading CDC ECM host_addr", gadgetName))
|
||||
return nil, err1
|
||||
@ -319,6 +321,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)
|
||||
if udc_name == udc_name_set {
|
||||
result.Enabled = true
|
||||
}
|
||||
@ -343,7 +346,7 @@ func DeployGadgetSettings(settings pb.GadgetSettings) error {
|
||||
|
||||
//create gadget folder
|
||||
os.Mkdir(USB_GADGET_DIR, os.ModePerm)
|
||||
log.Printf("Creating composite gadget '%s'", USB_GADGET_NAME)
|
||||
log.Printf("Creating composite gadget '%s'\nSettings:\n%+v", USB_GADGET_NAME, settings)
|
||||
|
||||
//set vendor ID, product ID
|
||||
ioutil.WriteFile(USB_GADGET_DIR+"/idVendor", []byte(settings.Vid), os.ModePerm)
|
||||
@ -495,7 +498,10 @@ func DeployGadgetSettings(settings pb.GadgetSettings) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ioutil.WriteFile(USB_GADGET_DIR+"/UDC", []byte(udc_name), os.ModePerm)
|
||||
log.Printf("Enabeling gadget for UDC: %s\n", udc_name)
|
||||
if err = ioutil.WriteFile(USB_GADGET_DIR+"/UDC", []byte(udc_name), os.ModePerm); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user