From 25b03414dc83a7b117e8acde28a81f79d5de20c9 Mon Sep 17 00:00:00 2001 From: deadprogram Date: Mon, 17 Apr 2023 14:38:15 +0200 Subject: [PATCH] machine/usb/hid/joystick: handle case where we cannot find the correct HID descriptor Signed-off-by: deadprogram --- src/machine/usb.go | 7 ++++++- src/machine/usb/descriptor/hid.go | 19 ++++++++++++++++--- src/machine/usb/hid/joystick/joystick.go | 2 +- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/machine/usb.go b/src/machine/usb.go index 7a72e164..a90fab17 100644 --- a/src/machine/usb.go +++ b/src/machine/usb.go @@ -302,7 +302,12 @@ func EnableMIDI(txHandler func(), rxHandler func([]byte), setupHandler func(usb. // EnableJoystick enables HID. This function must be executed from the init(). func EnableJoystick(txHandler func(), rxHandler func([]byte), setupHandler func(usb.Setup) bool, hidDesc []byte) { - class := descriptor.FindClassHIDType(descriptor.CDCJoystick.Configuration, descriptor.ClassHIDJoystick.Bytes()) + class, err := descriptor.FindClassHIDType(descriptor.CDCJoystick.Configuration, descriptor.ClassHIDJoystick.Bytes()) + if err != nil { + // TODO: some way to notify about error + return + } + class.ClassLength(uint16(len(hidDesc))) descriptor.CDCJoystick.HID[2] = hidDesc diff --git a/src/machine/usb/descriptor/hid.go b/src/machine/usb/descriptor/hid.go index 266d1006..925bb78d 100644 --- a/src/machine/usb/descriptor/hid.go +++ b/src/machine/usb/descriptor/hid.go @@ -3,6 +3,7 @@ package descriptor import ( "bytes" "encoding/binary" + "errors" ) var configurationCDCHID = [configurationTypeLen]byte{ @@ -76,10 +77,22 @@ func (d ClassHIDType) ClassLength(v uint16) { binary.LittleEndian.PutUint16(d.data[7:9], v) } -func FindClassHIDType(data, section []byte) ClassHIDType { - idx := bytes.Index(data, section) +var errNoClassHIDFound = errors.New("no classHID found") - return ClassHIDType{data: data[idx : idx+ClassHIDTypeLen]} +// FindClassHIDType tries to find the ClassHID class in the descriptor. +func FindClassHIDType(des, class []byte) (ClassHIDType, error) { + if len(des) < ClassHIDTypeLen || len(class) == 0 { + return ClassHIDType{}, errNoClassHIDFound + } + + // search only for ClassHIDType without the ClassLength, + // in case it has already been set. + idx := bytes.Index(des, class[:ClassHIDTypeLen-2]) + if idx == -1 { + return ClassHIDType{}, errNoClassHIDFound + } + + return ClassHIDType{data: des[idx : idx+ClassHIDTypeLen]}, nil } var classHID = [ClassHIDTypeLen]byte{ diff --git a/src/machine/usb/hid/joystick/joystick.go b/src/machine/usb/hid/joystick/joystick.go index cdcf771d..763b39ee 100644 --- a/src/machine/usb/hid/joystick/joystick.go +++ b/src/machine/usb/hid/joystick/joystick.go @@ -30,7 +30,7 @@ func UseSettings(def Definitions, rxHandlerFunc func(b []byte), setupFunc func(s State: def.NewState(), } if setupFunc == nil { - setupFunc = js.setupFunc + setupFunc = hid.DefaultSetupHandler } machine.EnableJoystick(js.handler, rxHandlerFunc, setupFunc, hidDesc) Joystick = js